求解构造哈夫曼树
4,5,6,7,10,12,15,18,23
6,7,9,10,12,15,18,23
9,10,12,13,15,18,23
12,13,15,18,19,23
15,18,19,23,25
19,23,25,33
25,33,42
42,58
100
这个讲的相当清楚。
首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。它是一种变长的编码。在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。(注:码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。)
然而怎样构造一棵哈夫曼树呢?最具有一般规律的构造方法就是哈夫曼算法。一般的数据结构的书中都可以找到其描述:
一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止。
用C语言实现上述算法,可用静态的二叉树或动态的二叉树。若用动态的二叉树可用以下数据结构: struct tree{
float weight; /*权值*/
union{
char leaf; /*叶结点信息字符*/
struct tree *left; /*树的左结点*/
};
struct tree *right; /*树的右结点*/
};
struct forest{ /*F集合,以链表形式表示*/
struct tree *ti; /* F中的树*/
struct forest *next; /* 下一个结点*/
};
例:若字母A,B,Z,C出现的概率为:0.75,0.54,0.28,0.43;则相应的权值为:75,54,28,43。
构造好哈夫曼树后,就可根据哈夫曼树进行编码。例如:上面的字符根据其出现的概率作为权值构造一棵哈夫曼树后,经哈夫曼编码得到的对应的码值。只要使用同一棵哈夫曼树,就可把编码还原成原来那组字符。显然哈夫曼编码是前缀编码,即任一个字符的编码都不是另一个字符的编码的前缀,否则,编码就不能进行翻译。例如:a,b,c,d的编码为:0,10,101,11,对于编码串:1010就可翻译为bb或ca,因为b的编码是c的编码的前缀。刚才进行哈夫曼编码的规则是从根结点到叶结点(包含原信息)的路径,向左孩子前进编码为0,向右孩子前进编码为1,当然你也可以反过来规定。
这种编码方法是静态的哈夫曼编码,它对需要编码的数据进行两遍扫描:第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并必须把树的信息保存起来,即把字符0-255(2^8=256)的频率值以2-4BYTES的长度顺序存储起来,(用4Bytes的长度存储频率值,频率值的表示范围为0--2^32-1,这已足够表示大文件中字符出现的频率了)以便解压时创建同样的哈夫曼树进行解压;第二遍则根据第一遍扫描得到的哈夫曼树进行编码,并把编码后得到的码字存储起来。 静态哈夫曼编码方法有一些缺点:一、对于过短的文件进行编码的意义不大,因为光以4BYTES的长度存储哈夫曼树的信息就需1024Bytes的存储空间;二、进行哈夫曼编码,存储编码信息时,若用与通讯网络,就会引起较大的延时;三、对较大的文件进行编码时,频繁的磁盘读写访问会降低数据编码的速度。
因此,后来有人提出了一种动态的哈夫曼编码方法。动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。动态哈夫曼编码比静态哈夫曼编码复杂的多,有兴趣的读者可参考有关数据结构与算法的书籍。
前面提到的JPEG中用到了哈夫曼编码,并不是说JPEG就只用哈夫曼编码就可以了,而是一幅图片经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。
最简哈夫曼树简介
理解数据结构是编程的基础,而树作为一种核心数据结构,其概念源于现实中的树木形态。它并非指真实的植物,而是指一种特殊的存储方式,通过分层结构和分支关系来组织数据,就像一棵有分支的树。哈夫曼树,是由德国数学家冯·哈夫曼在其研究中提出的一种重要树形结构,也被称为最简哈夫曼树。它的独特之...
用权值2, 3, 7, 8构造一棵哈夫曼树,并求其带权路径长度
哈夫曼树:20 \/ \\ 8 12 \/ \\ 5 7 \/ \\ 2 3 树带权路径长度是: 2 * 3 + 3*3 + 7*2 + 8*1 = 37
数据结构 哈夫曼树在构造时 有顺序要求吗 比如左右子树的顺序要固定什...
节点按照权值排序的规则,例如两个原始节点或者一个原始节点和一个新建节点,具有相同的权值时,需要统一序列中的前后顺序(序列中的前后顺序也就是确定哪个是左子节点和右子节点),目的仍然是满足构造出的哈夫曼树具有相同的结构#include<stdio.h> include<iostream> define INF 0x3f3f3f3f define MALL ...
怎么编哈夫曼树的编码和解码(用C语言,用文件读入已知的文本文件里的内容...
这个程序的本身是很长的 打起来也不是很好做 具体的来说算法的思想应该是将不同的结点从小到大排列后不断的用最小的两个组合来建立树 最后建立起来哈夫曼树 ,而起编码也是遵循的是左为0右为1的方法,根据叶子结点到根的路径读出他的编码.
怎样证明:一棵有n个叶子的哈夫曼树共有2n-1 个结点?
以后每次由1叶子与新结点产生新结点,故n个叶子共有2n-1个结点。2.剩下的叶子中又有2个叶子(比第1次产生的新结点权小)结合产生新结点,其它类似,那么必然会由2个都是新结点再产生新结点,所以实际上数量与第1种一样,共有2n-1个。具体证明用一个构造哈夫曼树的算法。
哈夫曼树有什么特点?
具体来说,哈夫曼树的构造过程如下:首先,将n个权值最小的叶子节点添加到一个优先队列中。然后,将优先队列中的两个权值最小的节点合并为一个新的节点,这个新节点的权值就是这两个节点的权值之和。然后将新节点重新插入到优先队列中。重复这个过程,直到优先队列中只剩下一个节点,这个节点就是最终...
给定权值7,6,3,32,5,26,12,9,构造相应的哈夫曼树,并计算其带权路径长度...
哈夫曼树是:100 \/ \\ 42 58 \/ \\ \/ \\ 17 25 26 32 \/ \\ \/ \\ 8 9 12 13 \/ \\ \/ \\ 3 5 6 7 树的带权路径长度为WPL = (3+5 + 6 +7)*4 + (9+ 12)*3 + (26+32)*2 = 263 ...
一道关于求哈夫曼编码的数据结构题,求解答
哈夫曼编码首先要构造哈夫曼树,其构造规则是从概率这个序列中选择两个最小结点的值构造一颗树,新的树根的权值为两个子树的概率权值和。如题中,首先选择0.02 和 0.03构造一颗树,将权值之和放回序列中,为:0.07 0.19 0.10 0.32 0.21 0.06 0.05 继续上述过程只剩下一颗树为止。最终哈...
哈夫曼树的带权路径长度最短是多少?
由五个带权值为9,2,3,5,14的叶子结点构成哈夫曼树,带权路径长度为67。给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
如果给定权值总数有N个,则其哈夫曼树的结点总数为多少
给定权值总数有N个,则其哈夫曼树的结点总数为2*N-1;给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。哈夫曼树只有叶子结点和度为2的结点,无度...
段哪乌拉: 其中每颗二叉树TI中只有一个带权WI的根节点,其左右子树为空.(2)在F中选取两颗根节点的权值最小的树作为左右子树构造一颗新的二叉树.parent=i;HT[i].lchild=s2;HT[i].rchild=s1;HT[i].weight=HT[s1].weight+HT[s2].weight.这棵树就是哈弗曼...
张北县18048357890: 怎样构造合适的哈夫曼树? - ?
段哪乌拉: 来自百度百科:哈夫曼树构造方法: 假设有n个权值,则构造出的哈夫曼树有n个叶子结点. n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为: (1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点); (2) 在森...
张北县18048357890: 哈夫曼树怎样构造编码? - ?
段哪乌拉: 先编造哈夫曼树,哈夫曼树构造规则: 假设有n个权值,则构造出的哈夫曼树有n个叶子结点. n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为: (1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点); (2) ...
张北县18048357890: 哈夫曼树的构建过程 - ?
段哪乌拉: 哈夫曼树: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近. 哈夫曼树的构造: 假...
张北县18048357890: 哈夫曼树的构造,关键字如图 - ?
段哪乌拉: 哈夫曼树构造规则:假设有n个权值,则构造出的哈夫曼树有n个叶子结点. n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;(3)从森林中删除选取的两棵树,并将新树加入森林;(4)重复(2)、(3)步,直到森林中只剩一棵树为止 根据上述步骤得到的哈夫曼数是 (100) / \ (43) 57 / \ / \ (20) 23 (27) 30 / \ / \9 (11) 11 16 / \ 4 7
张北县18048357890: 数据结构,构造哈夫曼树,求树的带权路径长度用6个权值分别为6、13、18、30、7和16的结点构造一棵哈夫曼(Huffman)树,该树的带权路径长度为答... - ?
段哪乌拉:[答案] =6*4+7*4+13*3+30*2+16*2+18*2=219吧,根结点的值不对哦
张北县18048357890: 编写一个程序,构造一棵哈夫曼树 - ?
段哪乌拉: #include<stdio.h> #include<string.h> #define N 50 //叶子结点数 #define M 2*N-1 //树中结点总数 typedef struct { char data[5]; //节点值int weight; //权重int parent; //双亲结点int lchild; //左孩子结点int rchild; //右孩子结点 }htnode; typedef ...
张北县18048357890: 构造哈夫曼树 - ?
段哪乌拉: 第一步排序 2 3 6 7 10 19 21 32 构图如下 谢谢提醒 我粗心了…… 字符版 复制到记事本里看********o********** *******/*\********* *****o*****o******* ****/*\***/*\****** ***19*21**o**32**** *********/*\******* ********o***o****** *******/*\*/*\***** *******o*6*7*10**** ******/*\********** ******2*3**********
张北县18048357890: 哈夫曼树是什么?求解 - ?
段哪乌拉: 哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如JPEG中就应用了哈夫曼编码.首先介绍什么是哈夫曼树.哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上...
张北县18048357890: 设给定一个权值集合W=(3,5,7,9,11),要求根据给定的权值集合构造一棵哈夫曼树 - ?
段哪乌拉: 设给定一个权值集合W=(3,5,7,9,11),要求根据给定的权值集合构造一棵哈夫曼树 夫曼树的构造: (1)根据给定的n个权值{w1,w2,...,wn}构造n棵二叉树的集合F={T1,T2,...,Tn},其中Ti中只有一个权值为wi的根结点,左右子树为空; (2)在F中...