HuffMan tree
定义
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
基础知识
- 路径:从树中的一个结点到另一个结点之间的分支构成这两点之间的路径
- 路径长度:路径上的分支数目称作路径长度
- 树的路径长度:从树根到每一个结点的路径长度之和
- 权:赋予某个实体的一个量
- 结点的带权路径长度:从该结点到树根之间的路径长度与结点上权的乘积
- 树的带权路径长度:树中所有叶子结点的带权路径长度之和
哈夫曼编码跟 ASCII 编码有什么区别?ASCII 编码是对照ASCII 表进行的编码,每一个字符符号都有对应的编码,其编码长度是固定的。而哈夫曼编码对于不同字符的出现频率其使用的编码是不一样的。其会对频率较高的字符使用较短的编码,频率低的字符使用较高的编码。这样保证总体使用的编码长度会更少,从而实现到了数据压缩的目的。
哈夫曼树的构造
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
例如:对 2,3,4,6 这四个数进行构造
huffman存储结构就是采用二叉树存储方式中的一种静态存储(二叉链表的静态结构)

因为每次要找到序列中权值最小的进行合并,所以在创建哈夫曼树时采用优先级队列,每次取出最小值。
列表中由n个数据,构建出来的哈夫曼树就有2*n - 1个节点

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <functional>
#include <ios>
#include<iostream>
#include<vector>
#include<string.h>
#include<stack>
#include<math.h>
#include<cstring>
#include<queue>
using namespace std;const int n = 8;
const int m = 2 * n;
typedef unsigned int WeightType;
typedef unsigned int NodeType;typedef struct {WeightType weight;NodeType parent, leftchild, rightchild;
}HTNode;typedef HTNode HuffManTree[m];
typedef struct {char ch;char code[n + 1];
}HuffManCode;
typedef HuffManCode Huffcode[n + 1];void InitHuffManTree(HuffManTree &hft, WeightType w[]){memset(hft, 0, sizeof(HuffManTree));for(int i = 0; i < n; ++i){hft[i + 1].weight = w[i];}
}
void PrintHuffManTree(HuffManTree hft){for(int i = 1; i < m; ++i){printf("index :%3d weight : %3d parent: %3d leftchild %3d rightchild %3d\n" ,i, hft[i].weight, hft[i].parent, hft[i].leftchild, hft[i].rightchild);}printf("\n");
}
struct IndexWeight{int index;WeightType weight;operator WeightType() const {return weight;}
};
void CreateHuffManTree(HuffManTree hft){std::priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight> > qu;for(int i = 0; i <=n; ++i){qu.push(IndexWeight{i, hft[i].weight});}int k = n + 1;while(!qu.empty()){if(qu.empty()) break;IndexWeight left = qu.top();qu.pop();if(qu.empty()) break;IndexWeight right = qu.top(); qu.pop();hft[k].weight = left.weight + right.weight;hft[k].leftchild = left.index;hft[k].rightchild = right.index;hft[left.index].parent = k;hft[right.index].parent = k;qu.push({k, hft[k].weight});k += 1;}
}
void InitHuffManCode(Huffcode hc, const char * ch){memset(hc, 0, sizeof(HuffManCode));for(int i =1 ;i <= n; ++i){hc[i].ch = ch[i -1];hc[i].code[0] = '\0';}
}void PrintHuffCode(Huffcode hc){for(int i = 1; i <= n; ++i){printf("data : %c ->code %s\n", hc[i].ch, hc[i].code);}printf("\n");
}
void CreateHuffCode(HuffManTree hft, Huffcode hc){char code[n + 1] = {0};for(int i = 1; i <= n; ++i){int k = n;code[k] = '\0';int c = i;int pa = hft[c].parent;while(pa != 0){code[--k] = hft[pa].leftchild == c ? '0' : '1';c = pa;pa = hft[c].parent;}strncpy(hc[i].code, &code[k], n);}
}
int main(){WeightType w[n] = {5,29,7,8,14,23,3,11};char ch[n + 1] = {'A','B', 'C', 'D', 'E', 'F', 'G', 'H'};HuffManTree hft = {0};Huffcode hc = { 0};InitHuffManTree(hft, w);InitHuffManCode(hc, ch);PrintHuffManTree(hft);PrintHuffCode(hc);CreateHuffManTree(hft);CreateHuffCode(hft, hc);PrintHuffManTree(hft);PrintHuffCode(hc);return 0;
}

参考:
https://blog.csdn.net/Initial_Mind/article/details/124354318
相关文章:
HuffMan tree
定义 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 基础知识 路…...
各地加速“双碳”落地,数字能源供应商怎么选?
作者 | 曾响铃 文 | 响铃说 随着我国力争2030年前实现“碳达峰”、2060年前实现“碳中和”的“双碳”目标提出,为各地区、各行业的低碳转型和绿色可持续发展制定“倒计时”时间表,一场围绕“数字能源”、“智慧能源”、“新能源”等关键词的创新探索进…...
19.java绘图
A.Graphics类 Graphics类是java.awt包中的一个类,它用于在图形用户界面(GUI)或其他图形应用程序中进行绘制。该类通常与Component的paint方法一起使用,以在组件上进行绘制操作。 一些Graphics类的常见用法和方法: 在组…...
提升工作效率,尽在Microsoft Office LTSC 2021 for Mac!
在当今的办公环境中,高效率的工作是每个人都追求的目标。作为全球领先的办公软件套装,Microsoft Office LTSC 2021 for Mac将为您提供一站式的解决方案,帮助您轻松应对各种工作任务。 首先,Microsoft Office LTSC 2021 for Mac拥…...
day24_java的反射机制
反射 一、反射的概念 反射:加载类,反射出类的各个组成部分(类的成员:构造方法,属性,方法) java反射机制:在运行状态中,对于任何一个类都能够知道这个类的所有属性和方…...
VUE学习二、创建一个前端项目
1.创建一个vue项目 使用命令 vue ui启动vue脚手架 vue ui 等待项目创建好 可以来任务栏启动项目 参数那里可以设置启动端口等参数 启动成功 成功访问 2. 用webstorm 打开项目 脚手架页面可安装基本依赖 比如路由 使用ws打开项目 启动项目 npm run serve 3.修改启动…...
「红队笔记」靶机精讲:Prime1 - 信息收集和分析能力的试炼
「红队笔记」靶机精讲:Prime1 - 信息收集和分析能力的试炼 本文是作者在观看 B 站《红队笔记》后做的一些笔记及相关知识的补充。学渗透特别推荐大家去看。如有侵权,请联系作者,作者看到后会第一时间删除。 靶机精讲之Prime1,vu…...
JVM虚拟机系统性学习-对象的创建流程及对象的访问定位
对象的创建流程与内存分配 对象创建流程如下: Java 中新创建的对象如何分配空间呢? new 的对象先放 Eden 区(如果是大对象,直接放入老年代)当 Eden 区满了之后,程序还需要创建对象,则垃圾回收…...
perf与火焰图-性能分析工具
参考链接 perf性能分析工具使用分享 如何读懂火焰图?-阮一峰 perf基本用法-record,report-知乎 火焰图抓取 准备: centos安装perf工具 dnf install perf下载火焰图解析代码 git clone https://github.com/brendangregg/FlameGraph.git抓取指定进程…...
UniGui使用CSSUniTreeMenu滚动条
有些人反应UniTreeMenu当菜单项目比较多的时候会超出但是没有出滚动条,只需要添加如下CSS 老规矩,unitreemeu的layout的componentcls里添加bbtreemenu,然后在css里添加 .bbtreemenu .x-box-item{ overflow-y: auto; } 然后当内容超出后就会…...
Spring框架中的五种常用设计模式
1、单例模式 Spring 的 Bean 默认是单例模式,通过 Spring 容器管理 Bean 的⽣命周期,保证每个 Bean 只被 创建⼀次,并在整个应⽤程序中重用。 2.工厂模式 Spring 使⽤⼯⼚模式通过 BeanFactory 和 ApplicationContext 创建并管理 Bean 对象…...
华纳云:docker启动报错的原因和解决方法
Docker 启动报错可能由多种原因引起。以下是一些建议,可用于解决 Docker 启动问题: 查看 Docker 日志: 查看 Docker 的日志可以提供更多的详细信息,有助于定位问题。 sudo journalctl -xe | grep docker 或者查看 Docker 服务的详…...
代码规范及开发工具
代码规范及开发工具: 前端(vscode、idea): JavaScript规范: 1. 谷歌开源项目风格指南:JavaScript 、TypeScript篇 https://zh-google-styleguide.readthedocs.io/en/latest/google-typescript-…...
证件照制作小程序源代码
17638103951(同v)...
自治调优!人大金仓解放DBA双手
数据库系统的性能是确保整个应用系统高效运转的关键因素,因此数据库性能调优工作至关重要。KingbaseES通过将人工调优过程内化为数据库内核,成功实现了自治调优。这种创新的调优方案为DBA提供了更高效且准确的性能调优途径,同时也显著降低了数…...
深度学习环境配置------windows系统(GPU)------Pytorch
深度学习环境配置------windows系统(GPU)------Pytorch 准备工作明确操作系统明确显卡系列 CUDA和Cudnn下载与安装1.下载2.安装 环境配置过程1.安装Anacoda2.配置环境1)创建一个新的虚拟环境2)pytorch相关库的安装 2.安装VScode1&…...
el-menu标题过长显示不全问题处理
项目基于vue-element-admin 问题 期望 处理方式 \src\layout\components\Sidebar\index.vue 文件后添加CSS <style scped> /* 侧栏导航菜单经典 文字超长溢出问题 CSS折行 */ .el-submenu__title {display: flex;align-items: center; } .el-submenu__title span {white-…...
微信游戏开发:连接社交与娱乐的创新之路
在移动互联网时代,微信已经成为了人们日常生活中不可或缺的社交工具。而微信游戏,作为在这一平台上崛起的新兴产业,不仅给用户提供了更多娱乐选择,也为开发者们创造了独特的机遇。本文将探讨微信游戏开发的关键步骤、技术要点以及…...
1688一件采购实现指南:含代码实现采购流程
一、引言 1688是中国最大的B2B电子商务平台之一,提供了丰富的商品信息和采购服务。一键采购是1688平台的一项便捷功能,可以帮助用户快速完成采购流程,提高采购效率。本文将详细介绍如何使用1688一键采购功能,并通过代码示例演示如…...
div中一个图片怎么铺满整个div而且不超出div按比例铺满div
重要信息: background-size:cover或者background-size:contain;属性 设置图片不重复: background-repeat:no-repeat; 设置字体在div中间:...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
