哈夫曼树--数据结构
文章目录
- 哈夫曼树
- 哈夫曼树的特点
- 构造哈夫曼树算法
- 哈夫曼编码
- 示例
- 哈夫曼树构造代码
- 示例
- 哈夫曼编码和二进制编码的比较
哈夫曼树
哈夫曼树,又称最优树,时一类带权路径长度最短的树。
从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称做路径长度。
树的路径长度是从树根到每一结点的路径长度之和。
树的带权路径长度为树中所有叶子结点的带权路径长度之和,通常记作 WPL = ω1l1 + …… + ωnln
假设有 n 个权值{ ω1,ω2,……,ωn },试构造一棵有 n 个叶子结点的二叉树,每个叶子结点带权为 ωi,则其中带权路径长度 WPL 最小的二叉树称做最优二叉树或哈夫曼树。
(a)WPL = 7×2+5×2+2×2+4×2=36;
(b)WPL = 7×3+5×3+2×1+4×2=46;
(c)WPL = 7×1+5×2+2×3+4×3=35;
其中(c)树最小。可以验证它恰好为哈夫曼树,即其带权路径长度在所有带权为7、5、2、4的 4 个叶子结点的二叉树中居最小。
哈夫曼树的特点
- WPL最小
- 给定权值的哈夫曼树可能不只一棵
- 只有度为 2,度为 0 的结点—正则的(严格的)二叉树
- 一棵有 n 个叶子结点的哈夫曼树共有 2n-1 个结点
- 权值越大的叶结点越靠近根结点,而权值越小的叶结点越远离根结点
构造哈夫曼树算法
- 根据给定的 n 个权值 {ω1,ω2,……,ωn} 构成 n 棵二叉树的集合 F={T1,T2,……,Tn},其中每棵二叉树 Ti 中只有一个带权为 ωi 的根结点,其左右子树均空。
- 在 F 中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
- 在 F 中删除这两棵树,同时将新得到的二叉树加入 F 中。
- 重复 1 和 2,直到 F 只含一棵树为止。这棵树便是哈夫曼树。
哈夫曼编码
若采用相同长度的不同码字代表相应的符号,就称为等长编码。
若要设计长短不等的编码,则必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码称做前缀编码。
可以利用二叉树来设计二进制的前缀编码。约定左分支表示字符‘0’,右分支表示字符‘1’(左0右1),则可以从根结点到叶子结点的路径上分支字符组成的字符串作为该叶子结点字符的编码。如此得到必为二进制前缀编码,二进制前缀编码也被称为哈夫曼编码。
示例
假设用于通信的电文由字符集{a,b,c,d,e,f,g}中的字母构成。它们在电文中出现的频度分别为 {0.31,0.16,0.10,0.08,0.11,0.20,0.04}
为这7个字母设计哈夫曼编码
为这7个字母设计等长编码,至少需要几位二进制数?
哈夫曼编码比等长编码使电文总长压缩多少?
先对权值进行排序。
每次从序列中取出两个结点。然后构成一个结点,重新放回序列。
然后再次重复操作,直至,队列剩余一个结点为止。
等长编码位数相同表示 7 种符号至少需要 3 位二进制位。
23 =8,所以需要三位二进制数
等长二进制三位共100个字符,占用100 * 3 = 300
哈夫曼编码:2 * 20+ 3 * 10+11* 3+4 * 4+8 * 4+16 * 3+ 31 * 2 = 261
压缩:(300 - 261)/ 300 = 0.13
哈夫曼树构造代码
typedef struct{unsigned int weight;unsigned int parent,lchild,rchild;
}HTNode, *HuffmanTree; //动态分配数组存储哈夫曼树
typedef char **HuffmanCode; //动态分配数组存储哈夫曼编码表 void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){//w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC if(n <= 1)//字符小于一个 return;m = 2 * n - 1;//m为生成的中间节点个数 HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); //0号单元未用 for(p = HT, i = 1; i <= n; i++, p++, w++)//字符初始化 *p = {*w, 0, 0, 0};for(; i <= m; i++, p++)//中间节点初始化 *p = {0, 0, 0, 0};for(i = n+1; i<= m; i++){ //建哈夫曼树 //在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2 Select(HT, i-1, s1, s2);HT[s1].parent = i;HT[s2].parent = i;HT[i].lchild = s1;HT[i].rchild = s2;HT[i].weight = HT[s1].weight + HT[s2].weight;}//从叶子到根逆向求每个字符的哈夫曼编码 HC = (HuffmanCode)malloc((n+1) * sizeof(char *));//分配n个字符编码的头指针向量 cd = (char *)malloc(n * sizeof(char));//分配求编码的工作空间 cd[n-1] = "\0";//编码结束符 for(i = 1; i <= n; i++){ //逐个字符求哈夫曼编码 start = n - 1;//编码结束符位置 for(c = i, f = HT[i].parent; f!=0; c = f, f = HT[f].parent){//从叶子到根逆向求编码 if(HT[f].lchild == c)cd[--start] = "0";elsecd[--start] = "1";}HC[i] = (char *)malloc((n-start) * sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i], &cd[start]);//从cd复制编码(串)到HC }free(cd);//释放工作空间
}
示例
已知某系统在通信联络中只可能出现 8 种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,3.11,试设计哈夫曼编码。
哈夫曼编码和二进制编码的比较
- 码字不同。 哈夫曼所构造的码字不是唯一的,对于同一信息源,无论上述的顺序如何排序,它的平均码长是不会改变,所以他的优点是编码效率唯一性。而二进制编码所构成的码字是唯一。
- 长度不同。 哈夫曼树是依据字符出现概率来构造异字头的平均长度最短的码字,比较精准,二进制编码用预计规定的方法将文字、数字或其他对象编成二进制的数码,或将信息、数据转换成二进制电脉冲信号。二进制是最基础的编码。
- 稳定性不同。 哈夫曼编码的稳定性。如果改变其中一位数据就会产生改变。二进制编码具有抗干扰能力强,可靠性高等优点。
哈夫曼树--数据结构相关推荐
- c语言霍夫曼函数,使用C语言详解霍夫曼树数据结构
1.基本概念 a.路径和路径长度 若在一棵树中存在着一个结点序列 k1,k2,--,kj, 使得 ki是ki+1 的双亲(1<=i 从 k1 到 kj 所经过的分支数称为这两点之间的路径长度,它 ...
- 【赫夫曼树数据结构及其应用】
本文主要介绍Java中赫夫曼树数据结构的基本原理.实现方式以及使用场景.赫夫曼树(Huffman Tree)是一种带权路径最短的二叉树,广泛应用于数据压缩和编码等领域. 一.赫夫曼树的基本概念 赫夫曼 ...
- Huffman-哈夫曼树-数据结构
哈夫曼树 #include "iostream" #include "string.h" using namespace std;//定义哈夫曼树存储结构 ty ...
- 数据结构源码笔记(C语言):哈夫曼树
#include <stdio.h> #include <stdlib.h> #define MAXINT 2147483647 #define MAXNUM 50 #defi ...
- 数据结构——树、二叉树、森林、哈夫曼树、字符串模式匹配
%%%%%% 字符串模式匹配算法--详解KMP算法 https://blog.csdn.net/zc474235918/article/details/40474525 http://www.ruan ...
- 【数据结构】哈夫曼树与哈夫曼编码
定义 带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值wkw_kwk,从根节点到每个叶子结点的长度为lkl_klk,则每个叶子结点的带权路径长度之和就是:WPLWPLWPL=∑ ...
- 数据结构题:根据所给权值设计相应的哈夫曼树,并设计哈夫曼编码
文章目录 前言 一.涉及到的知识点 二.例题讲解 1.例题1 2.例题2 总结 前言 在数据结构树的这章中,常常有题目,是这样的"给定一组权值-,试设计相应的哈夫曼树",有的还要求 ...
- 数据结构(哈夫曼树,哈夫曼编码)入门篇,JAVA实现
什么是哈夫曼树 哈夫曼树就是一种最优判定树,举个例子,如下一个判断逻辑 if(s<60) g=1; else if(s<70) g=2 else if(s<80) g=3 else ...
- 数据结构(哈夫曼树+KMP)之 数据加密+解密
数据结构(哈夫曼树+KMP)之 数据加密+解密 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> #define N 1 ...
最新文章
- 丢弃Transformer,FCN也可以实现E2E检测
- 字符集GBK和UTF8的区别说明
- centos给用户添加sudo权限
- 实用的java代码生成器,开箱即用(基于mybatisplus的AutoGenerator)
- machinery入门看这一篇(异步任务队列)
- php ajax勾选框提交,jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例...
- es6笔记6^_^generator
- CTR预估之outbrain
- [计算机网络][内容梳理]四、网络层
- 智慧树工业机器人测试答案_智慧树_工业机器人技术基础_答案章节单元测试答案...
- uni-app详情页开发
- 信息学奥赛 java C 选_信息学奥赛(NOIP)入门指南(新家长必读)
- 电视显示通路故障或服务器不可用,百视通电视魔百和故障处理手册
- 初级程序员 中级程序员_急切的程序员
- win10的word如何取消分页符
- 【商城报错】-商品上架功能报错
- 设立分公司,还是子公司更省税
- Matlab如何进行利用离散傅里叶变换DFT (快速傅里叶变换FFT)进行频谱分析
- envi处理海思一号数据全过程详解
- Linux课堂笔记--第九天
热门文章
- Spark RDD 简述
- 单元格下拉全选快捷键_EXCEL筛选后把某一列全选,用什么快捷键。我用CTRL+SHIFT+下方向键总是全选,为什么?求教!...
- Javascript 历史遗留 - 产生的语法问题整理
- 一图带你了解人工智能简史
- CentOS 7 yum 安装 pip3 和 python3.6
- CSS重复线性渐变之画格子
- mysql router是什么_数据库周刊28│开发者最喜爱的数据库是什么?阿里云脱口秀聊程序员转型;MySQL update误操作...
- 使用layui把数据以Excel格式导出
- 组播路由协议——PIM DM工作机制
- 允许网站使用相机和麦克风_通过浏览器获取麦克风或相机等媒体的使用权限