数据结构与算法(十一)哈夫曼树及其应用
路径:树中一个结点到另一个结点之间的分支所构成的路径
路径长度:两个结点之间的分支数
树的路径长度:从根结点到每个结点的路径长度之和,记作TL
结点数目相同的二叉树中,完全二叉树是路径长度最短的
结点的带权路径长度:根到该结点之间路径长度 X 该结点的权
树的带权路径长度:所有叶子结点的带权路径长度之和
记作WPL=
哈夫曼树:最优二叉树(带权路径长度(WPL)最短的树)
满二叉树不一定是哈夫曼树
哈夫曼树中权越大的叶子离根越近(贪心算法)
哈夫曼算法
1.根据n个给定的权值{w1,w2,...2n}构成n棵二叉树森林F={T1,T2,...,Tn},其中Ti只有一个带权为wi的根结点。(构造森林全是根)
2.从F中选择两个权值最小的作为左右子树来构造一颗新的二叉树(新二叉树根结点的权值为左右子树根结点之和)(选用两小造新树)
3.删除原来的两颗树,将新树加入森林(删除两小添新人)
4.重复步骤2-3,直到森林中仅剩一棵树(重复2、3剩单根)
例1:a,b,c,d权值分别为7,5,2,4
哈夫曼树只有度为0或2的结点,没有度为1的结点
包含n个叶子结点的哈夫曼树共有2n-1个结点
n棵二叉树要经历n-1次合并可以形成哈夫曼树
例2:a,b,c,d,e权值分别为7,5,5,2,4
算法实现
使用顺序存储结构实现--结构数组
weight(权重),parent(父母),lch,rch(左右孩子)
哈夫曼树中共2n-1个结点,不使用0为下标,需要数组大小2n
1.初始化HT[1...2n-1]:lch=rch=parent=0
2.输入初始n个叶子结点:设置HT[1...n]的weight值
3.进行n-1次合并
a.从HT[1...i-1]中选取连个未选择的(parent=0)weight最小的两个结点
b.修改HT[S1],HT[S2]的值,HT[S1].parent=HT[S2].parent=i
c.修改新产生的HT[i] HT[i].weight=HT[S1].weght+HT[S2].weight;
HT[i].lch=S1; HT[i].ch=s2;
void CreateHuffmanTree(HuffmanTree HT,int n){if(n<=1) return;m = 2*n-1;//数组共2n-1个元素HT=new HTNode[m+1]; //0单号未用,HT[m]表示根结点for(i=1;i<=m;++i){HT[i].lch=0; HT[i].rch=0; HT[i].parent=0;}for(i=1;i<=n;++i) cin>>HT[i].weight;//输入前n个weight值///*********初始化结束***********///for(i=n+1;i<=m;i++){Select(HT,s1,s2);//在HT中选择连个双亲域为0且权值最小的结点HT[s1].parent=i; HT[s2].parent=i;//删除s1,s2HT[i].lch=s1; HT[i].rch=s2; //s1,s2作为左右孩子HT[i].weight=HT[s1].weight+HT[s2].weight;//设置新权值}
}
应用:哈夫曼编码
不定长二进制编码,出现次数多的尽可能短(节约空间)!!!任意一个字符的编码不能是另一个字符编码的前缀--前缀编码
哈夫曼树: 1.统计字符在电文中出现的平均概率
2.根据平均概率构造哈夫曼树
3.结点左分支标0,右分支标1;把从根到每个叶子结点的路径上的标号连接起来,作为该叶子代表的字符编码
哈夫曼编码中每个字符(叶子结点)的编码(路径)都不会经过其他字符,所以不存在某个字符的编码是其他字符的前缀
哈夫曼编码的实现
1.查找该字符的双亲结点,并确定其是左孩子还是右孩子。
2.在临时存储区域中标注当前结点的状态,如果为左孩子标0,右孩子标1
3.将临时空间向前移动一位寻找下一个双亲结点,直到找到根结点为止
例
以第三个字符C为例
start | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Loc | 13 | 12 | 11 | 3 | |||
parentLoc | 0 | 13 | 12 | 11 | |||
childTag | root | 1 | 0 | 1 | \0 |
Loc为结点自己的位置,parentLoc为双亲结点的位置,childTag为该结点是左孩子还是右孩子,讲childTag连接起来就是该字符的哈夫曼编码,\0为编码结束的标志
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC ,int n){HC = new char*[n+1];//分配n个字符编码的头指针矢量cd = new char[n];//分配临时存放编码的动态数组cd[n-1] = '\0' //编码结束符for(i=1;i<=n;++i){start=n-1; c=i; f=HT[i].parent;while(f!=0){ //从叶子结点开始向上回溯,直到根结点--start; //回溯一次start向前指一个位置if(HT[f].lchild == c) cd[start] = '0';//结点c为f的左孩子,标0else cd[start] = '1';//结点c为f的右孩子,标1c=f; f=HT[f].parent; //向上回溯} //求第i个字符的编码HC[i]= new char[n-start];//为第i个字符的编码分配空间strcopy(HC[i],$cd[start];)//将求得的编码从临时空间cd复制到hc中}delete cd;//释放临时空间
}
哈夫曼树的应用:
1.编码文件 ①输入各字符的权值
②构造哈夫曼树HT[i]
③进行哈夫曼编码HC[i]
④查HC[i],得到各字符的哈夫曼编码
2.解码文件 ①构造哈夫曼树
②一次读入二进制编码
③读入0,则走向左孩子;读入1,则走向右孩子
④一旦到达某叶子时,即可译出字符
⑤然后从根出发继续译码,直到结束
原文为uvuwxxxvywyuyyvxxyxxuxuvvyvxy
数据结构与算法(十一)哈夫曼树及其应用相关推荐
- 数据结构与算法学习④(哈夫曼树 图 分治回溯和递归)
数据结构与算法学习④(哈夫曼树 图 回溯和递归 数据结构与算法学习④ 1.哈夫曼树 1.1.相关概念 1.2.哈夫曼树的构建 1.3.哈夫曼编码 1.4.面试题 2.图 2.1.图的相关概念 2.2. ...
- 【数据结构与算法】-哈夫曼树(Huffman Tree)与哈夫曼编码
超详细讲解哈夫曼树(Huffman Tree)以及哈夫曼编码的构造原理.方法,并用代码实现. 1哈夫曼树基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径. 结点的路径长度:两 ...
- Java数据结构和算法:哈夫曼树
本章介绍哈夫曼树.和以往一样,本文会先对哈夫曼树的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可.若 ...
- 【数据结构与算法】哈夫曼树的Java实现
哈夫曼树 最优二叉树也称哈夫曼树,讲的直白点就是每个结点都带权值,我们让大的值离根近.小的值离根远,实现整体权值(带权路径长度)最小化. 哈夫曼算法的思想我认为就是上面讲的,而它的算法实现思路是这样的 ...
- 《数据结构与算法之哈夫曼树(Java实现)》
说在前头: 本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,能力有限,文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正. ...
- 【数据结构和算法】赫夫曼树 | 实战演练
- 【数据结构和算法】赫夫曼树 | 实战演练(二)
- 【C语言-数据结构与算法】-哈夫曼压缩解压缩-终局-如何做一个自己独有的压缩软件
哈夫曼压缩&解压缩 Ⅰ 前言 Ⅱ 需求分析&主函数带参的应用 A. 需求分析 B. 压缩部分 B. 解压缩部分 Ⅲ 哈夫曼压缩 A. 代码分析 B. 从文件中读取内容生成频度表 C. ...
- 【大话数据结构算法】哈夫曼树
哈夫曼树又称为最优二叉树. 1.路径和路径长度 在一棵树中,从一个节点往下可以达到的孩子或者子孙节点之间的通路称为路径.通路中分支的数目称为路径长度.若规定根节点的层数为1,则从根节点 到第L层节点的 ...
- 数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
哈夫曼树Huffman tree 又称最优完全二叉树,切入正题之前,先看几个定义 1.路径 Path 简单点讲,路径就是从一个指定节点走到另一个指定节点所经过的分支,比如下图中的红色分支(A-> ...
最新文章
- chrome手机模拟器显示尺寸不正确
- UART串口通信浅谈之(二)--寄存器设置
- 0/1背包问题——动态规划方法
- 所想即所得 运维进行时
- 实用知识点梳理:BGP协议、调制解调技术、路由特点、VOIP、FTP、Cookie、滑动窗口协议与自动重传请求
- 圆周移位是怎么移的_想烟道移位,师傅却连连摆手:小区烟道都是统一的,咋能随便改...
- CodeCraft-20 (Div. 2) C. Primitive Primes 思维 + 数论
- ICPC Trainings Moscow2020 K. King and Zeroing 树直径 + 思维
- mysql 深胡_Mysql胡说八道
- linux安装nodejs一键脚本,ubuntu16.04部署nodejs+vue框架脚本
- 白话中台战略:中台是个什么鬼?
- 【Processing学习笔记】安装与入门
- scrapy爬虫—获取script中的data数据
- 如何安装uclient_UClient客户端下载_UClient客户端官方下载-太平洋下载中心
- idea 快捷键大全
- Java软件工程师职业规划
- 文献笔记:Plasmonic metagratings for simultaneous determination of Stokes parameters
- pentaho开源商业智能平台的搭建
- 去除WMP10上面的东方宽屏图标
- 对VR来说, 眼球追踪技术在里面到底是一个什么角色?