哈夫曼编码

合集下载

哈夫曼树等长编码

哈夫曼树等长编码

哈夫曼树是一种特殊的二叉树,其中的每个叶子节点都代表一个字符,而从根节点到每个叶子节点的路径可以形成一个二进制编码,称为哈夫曼编码。

哈夫曼编码是一种不等长的编码方式,每个字符的编码长度是根据字符出现的频率来决定的。

具体来说,对于一个给定的字符集,我们可以首先根据每个字符的出现频率构造一棵哈夫曼树,然后从根节点到每个叶子节点的路径就可以形成一个二进制编码。

出现频率高的字符的编码长度较短,而出现频率低的字符的编码长度较长。

在哈夫曼编码中,由于每个字符的编码都是从根节点到该字符所代表的叶子节点的路径,因此可以根据编码的长度来判断字符的出现频率。

一般来说,长度较短的编码对应出现频率较高的字符,而长度较长的编码对应出现频率较低的字符。

需要注意的是,哈夫曼编码是一种前缀编码,即任何一个字符的编码都不是另一个字符编码的前缀。

这意味着在解码时,我们可以通过比较编码的长度来逐个解码出原始的字符序列,而不会出现二义性。

哈夫曼编码python

哈夫曼编码python

哈夫曼编码python一、什么是哈夫曼编码?哈夫曼编码(Huffman Coding)是一种可变长度编码(Variable Length Code),它可以将不同长度的字符编码成等长的二进制串,从而实现数据压缩的目的。

哈夫曼编码是由David A. Huffman在1952年发明的,它是一种贪心算法,可以得到最优解。

二、哈夫曼编码原理1.字符频率统计在进行哈夫曼编码之前,需要先统计每个字符出现的频率。

通常使用一个字典来存储每个字符和其出现的次数。

2.构建哈夫曼树根据字符出现频率构建一个二叉树,其中频率越高的字符离根节点越近。

构建过程中需要用到一个优先队列(Priority Queue),将每个节点按照频率大小加入队列中,并将队列中前两个节点合并为一个新节点,并重新加入队列中。

重复这个过程直到只剩下一个节点,即根节点。

3.生成哈夫曼编码从根节点开始遍历哈夫曼树,在遍历过程中,左子树走0,右子树走1,直到叶子节点。

将路径上经过的0和1分别表示为0和1位二进制数,并把这些二进制数拼接起来,就得到了该字符的哈夫曼编码。

三、哈夫曼编码Python实现下面是一个简单的Python实现:1.字符频率统计```pythonfrom collections import Counterdef get_char_frequency(text):"""统计每个字符出现的频率"""return Counter(text)```2.构建哈夫曼树```pythonimport heapqclass HuffmanNode:def __init__(self, char=None, freq=0, left=None, right=None): self.char = charself.freq = freqself.left = leftself.right = rightdef __lt__(self, other):return self.freq < other.freqdef build_huffman_tree(char_freq):"""根据字符频率构建哈夫曼树"""nodes = [HuffmanNode(char=c, freq=f) for c, f inchar_freq.items()]heapq.heapify(nodes)while len(nodes) > 1:node1 = heapq.heappop(nodes)node2 = heapq.heappop(nodes)new_node = HuffmanNode(freq=node1.freq+node2.freq, left=node1, right=node2)heapq.heappush(nodes, new_node)return nodes[0]```3.生成哈夫曼编码```pythondef generate_huffman_codes(node, code="", codes={}): """生成哈夫曼编码"""if node is None:returnif node.char is not None:codes[node.char] = codegenerate_huffman_codes(node.left, code+"0", codes) generate_huffman_codes(node.right, code+"1", codes)return codes```四、使用哈夫曼编码进行压缩使用哈夫曼编码进行压缩的方法很简单,只需要将原始数据中的每个字符用对应的哈夫曼编码替换即可。

哈夫曼树的平均编码长度

哈夫曼树的平均编码长度

哈夫曼树的平均编码长度
哈夫曼树的平均编码长度是指使用哈夫曼编码时,哈夫曼编码的总码长,除以出现的信息总字节数。

它是度量信息压缩技术中重要的参数,可以清楚地反映出编码和信息压缩技术的效率。

一、哈夫曼树的平均编码长度
1. 定义:哈夫曼树的平均编码长度是指使用哈夫曼树编码时,编码的总码长,除
以出现的信息总字节数。

2. 原理:哈夫曼编码的原理是,将较小的权值编码成较短的编码,而将较大的权值编码成较长的编码,这样,编码的总码长度就做出了贡献,使得编码总码长度降低。

3.计算:哈夫曼平均编码长度L = (sum(Pi*Li))/n ,其中Pi为概率,Li为对应的编码长度,n为文件中字节的总数。

4.应用:哈夫曼树的平均编码长度的应用情况非常广泛,常用来衡量压缩文件效果,以及传输数据链路的时延。

二、改进哈夫曼树的平均编码长度
1.动态哈夫曼树的应用:给出的源符号中有一组能够极大地缩减信息压缩时间和空间的改进型哈夫曼树——动态哈夫曼树,它可以计算出最优策略,即编码总数最小,权重最小。

这样,编码长度就比普通哈夫曼树大大缩小,达到了节省时间和空间的效果。

2.属性的重新确定:哈夫曼树的平均编码长度可以通过重新确定源文件属性而实现优化,建立合适的文件数据结构和定义顺序,使编码缩短。

3.编码技术:编码技术也可以显著缩短哈夫曼树的平均编码长度,二进制及其它数据表示法也可以用于改进哈夫曼树的平均编码长度,减少压缩包的容量。

总结:哈夫曼树的平均编码长度对于信息压缩技术中有着重要的意义,可以反映出编码和信息压缩技术的效率,可以从动态哈夫曼树的应用,以及属性的重新确定,以及编码技术等来得到优化改进,并实现了信息压缩的效果。

哈夫曼编码代码

哈夫曼编码代码

哈夫曼编码代码哈夫曼编码代码 1因为哈夫曼树的特点是:叶子结点权值越大的,离根越近。

又因为构造不等长编码的原则是:字符使用频率越高,编码越短,故采用哈夫曼树进行编码可以得到最优前缀编码。

约定左分支标记为0, 右分支标记为 1哈夫曼编码代码 2为不浪费存储空间,动态分配一个长度为n(字符编码长度一定小于n) 的一维数组cd, 用来临时存放当前正在求解的第i 个字符的编码,当第i个字符的编码求解完毕后,根据数组cd的字符串长度分配HC[i]的空间,然后将数组cd中的编码复制到HC[i]中。

依照上一篇文章的哈夫曼树:哈夫曼编码表HC:注意:由于哈夫曼树不唯一,故哈夫曼编码也不唯一。

代码如下:#include<stdio.h>#include<iostream>typedefstruct{int weight;int parent, lchild,rchild;}HTNode,*HuffmanTree;voidSelect(HuffmanTree&HT,int n,int&s1,int&s2){int min;for(int i =1; i <= n; i++){if(HT[i].parent ==0){min = i;break;}}for(int i =1; i <= n;i++){if(HT[i].parent ==0){if(HT[i].weight <HT[min].weight){min = i;}}}s1 = min;for(int i =1; i <= n;i++){if(HT[i].parent ==0&& i != s1){min = i;break;}}for(int i =1; i <= n;i++){if(HT[i].parent ==0&& i != s1){if(HT[i].weight < HT[min].weight){min = i;}}}s2 = min;}voidprintln(HuffmanTree &HT,intm){printf("==============================\n");for(inti =1; i <= m; i++){printf("%d, ", i);printf("%d ", HT[i].weight);printf("%d ", HT[i].parent);printf("%d ", HT[i].lchild);printf("%d \n",HT[i].rchild);printf("---------------------------\n");}}voidCreateHuffmanTree(HuffmanTree &HT,intn,int*ht){int i, m =2* n -1, s1, s2;if(n <=1)return;HT =new HTNode[m +1];for(i =1; i <= m;++i){HT[i].parent =0;HT[i].lchild =0;HT[i].rchild =0;}for(i =1; i <= n;++i){HT[i].weight = ht[i -1];}printf("\nHT的初态\n");println(HT, m);for(int i = n +1; i <=m;++i){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;}printf("\nHT的终态\n");println(HT, m);}typedefchar**HuffmanCode;char*cd;intstart;voidCreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC,int n){int i, c, f;HC =newchar*[n +1];cd =newchar[n];cd[n -1]='\0';for(i =1; i <= n;++i){start = n -1;c = i;f = HT[i].parent;while(f !=0){if(HT[f].lchild == c) cd[--start]='0';else cd[--start]='1';c = f;f = HT[f].parent;}HC[i]=newchar[n -start];strcpy(HC[i],&cd[start]);printf("第%d组--->", i);for(int j = start; j <= n -1;++j){printf("%c ",cd[j]);}printf("\n");}delete cd;}intmain(){HuffmanTree HT;HuffmanCode HC;int n =8;intht[8]={5,29,7,8,14,23,3,11};CreateHuffmanTree(HT, n, ht);CreatHuffmanCode(HT, HC, n);}运行结果:。

哈夫曼编码名词解释

哈夫曼编码名词解释

哈夫曼编码名词解释哈夫曼编码是一种用于数据压缩的编码方式。

由于它可以减小文件的体积,并且在传输文件时速度更快,因此在实际应用中非常重要。

哈夫曼编码一些重要的名词解释如下:一、频率频率是指特定字符在文本中出现的次数。

在哈夫曼编码中,频率用于计算每个字符的权重,权重越高的字符,使用的编码位数越少。

二、前缀码前缀码是指没有任何码字是其它码字的前缀的编码方式。

哈夫曼编码就是一种前缀码,没有任何哈夫曼编码的码字是其它码字的前缀,这是保证哈夫曼编码解码准确性的关键所在。

三、码树码树是一种包含权重、编码、二进制位数的树形数据结构。

在哈夫曼编码中,码树由文本中出现的字符的频率构成,每个字符用一个叶节点代表,叶节点和中间节点通过一个编码连接起来。

四、权重权重是指字符在文本中出现的频率,在哈夫曼编码中,它用于计算每个字符在编码中的位数,权重越高的字符使用的编码位数越少。

五、码字码字是指表示一个字符的二进制编码,长度不同的码字代表着不同权重的字符。

六、编码编码是将字符或数据转化为码字的过程,在哈夫曼编码中,通过经过计算得出的权重来生成码字。

七、解码解码是将码字转化为字符或数据的过程,在哈夫曼编码中,根据每个字符的码字和频率生成码树,在树中查找出对应的字符,从而将码字还原为原始的字符。

八、二进制二进制是计算机中表示数字的一种方式,它只包含0和1两种数值,在哈夫曼编码中,使用二进制来表示每个字符的码字。

总之,哈夫曼编码在很多领域都有着重要的应用,了解这些关键名词的含义将更好的理解和掌握它的原理,也会帮助你更好的使用它。

哈夫曼编码原理及方法

哈夫曼编码原理及方法

哈夫曼编码原理及方法哈夫曼编码(Huffman Coding)是一种变长编码(Variable Length Code)的压缩算法。

它的原理是将频率较高的字符用较短的编码,频率较低的字符用较长的编码,以此降低数据的传输成本。

下面将详细介绍哈夫曼编码的原理及方法。

一、哈夫曼编码的原理哈夫曼编码的原理基于贪心算法(Greedy Algorithm),即对每个要编码的字符进行评估,按照字符在文本中出现的频率多少,将频率高的字符赋予较短的编码,频率低的字符赋予较长的编码。

这样在实际使用中,字符出现频率越高的编码长度越短,从而达到压缩数据的目的。

二、哈夫曼编码的方法1. 构建哈夫曼树(Huffman Tree)构建哈夫曼树的过程首先要确定每个字符在文本中出现的频率,然后将每个字符看作一个节点,并按照其频率大小建立一个小根堆(Min Heap)。

接下来,选取频率最小的两个节点,将它们合并到一起作为一个新的节点,并更新频率值,然后继续重复以上步骤,直到堆中只剩下一个节点,即为哈夫曼树的根节点。

2. 生成哈夫曼编码生成哈夫曼编码可以采用递归的方式,从根节点开始向左遍历时,将标记为 0,向右遍历时,将标记为 1,直到叶节点为止,然后向上回溯,将遍历的结果保存下来,得到该叶节点的哈夫曼编码。

遍历完所有的叶子节点后,即可得到所有字符的哈夫曼编码。

3. 压缩数据在使用哈夫曼编码进行数据压缩时,将字符替换为其对应的哈夫曼编码,这样可以将原始数据压缩为更小的数据量,达到压缩数据的目的。

在解压数据时,需要根据已生成的哈夫曼树,将压缩后的数据转换为原始数据,即将哈夫曼编码转换为对应的字符。

三、哈夫曼编码的优缺点哈夫曼编码的优点是具有压缩比高、压缩速度快、压缩后的数据无损还原等特点,可以广泛用于图像、音频、视频等多种数据类型的压缩。

同时,由于哈夫曼编码采用变长编码方式,所以可以使用相对较短的编码表示经常出现的字符,从而达到更好的压缩效果。

定长编码与哈夫曼编码

定长编码与哈夫曼编码

定长编码与哈夫曼编码一、定长编码1.1 定长编码的定义和特点定长编码是一种将每个符号用固定长度的二进制代码表示的编码方式。

在定长编码中,每个符号的编码长度是固定的,不同的符号有不同的编码。

定长编码的特点包括:•每个符号的编码长度是相等的。

•不同的符号有不同的编码,因此可以唯一地解码出原始符号。

•编码长度固定,不依赖于符号的出现频率。

1.2 定长编码的应用和优缺点定长编码广泛应用于各种领域,例如通信、数据存储和信息传输等。

定长编码的主要优点和缺点如下:1.2.1 优点•简单易实现:定长编码的编解码过程简单,实现起来相对容易。

•解码效率高:由于每个符号的编码长度是固定的,解码时无需考虑编码长度的变化,因此解码效率较高。

•适用于等概率符号:对于每个符号出现的概率相等的情况,定长编码是一种很好的编码方式。

1.2.2 缺点•无法充分利用信息的统计特性:定长编码无法根据符号的出现频率来灵活地确定编码长度,因此在处理非等概率符号时,会导致编码的冗余度较高。

•编码效率较低:由于编码长度固定,无法根据符号的出现频率进行适当的压缩,因此编码效率较低。

二、哈夫曼编码2.1 哈夫曼编码的定义和原理哈夫曼编码是一种根据符号出现的概率进行变长编码的方法。

在哈夫曼编码中,频率较高的符号用较短的编码表示,频率较低的符号用较长的编码表示,从而提高编码效率。

哈夫曼编码的原理包括:1.统计每个符号出现的频率。

2.构建哈夫曼树:根据符号频率构建一棵二叉树,频率较低的符号在树的底部,频率较高的符号在树的顶部。

3.分配编码:从根节点开始,对树中的每个节点进行编码,左节点为0,右节点为1。

对于叶子节点,将其路径上的编码连接起来即为该符号的编码。

2.2 哈夫曼编码的应用和优缺点哈夫曼编码被广泛应用于数据压缩和信息传输等领域。

哈夫曼编码的主要优点和缺点如下:2.2.1 优点•编码效率高:根据符号出现的概率,将频率较高的符号用较短的编码表示,频率较低的符号用较长的编码表示,从而提高了编码效率。

哈夫曼编码

哈夫曼编码

哈夫曼编码一、概述哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VL C)的一种。

Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。

以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。

在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。

这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。

这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。

这种方法是由David.A.Huffman发展起来的。

例如,在英文中,e的出现概率很高,而z的出现概率则最低。

当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。

用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。

二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。

倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。

哈夫曼压缩属于可变代码长度算法一族。

意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。

因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。

二、C语言程序实现文件的huffman编码#include <stdio.h>#define MAX 1000#define MAXSYMBS 30#define MAXNODE 59typedef struct{int weight;int flag;int parent;int lchild;int rchild;}huffnode;typedef struct{int bits[MAXSYMBS];int start;}huffcode;void main(){huffnode huff_node[MAXNODE];huffcode huff_code[MAXSYMBS],cd;int i,j,m1,m2,x1,x2,n,c,p; /*char symbs[MAXSYMBS],symb;*//*数组buff_node初始化*/printf("please input the leaf num of tree:\n");scanf("%d",&n);for(i=0;i<2*n-1;i++){huff_node[i].weight=0;huff_node[i].parent=0;huff_node[i].flag=0;huff_node[i].lchild=-1;huff_node[i].rchild=-1;}printf("please input the weight of every leaf\n");for(i=0;i<n-1;i++)scanf("%d",&huff_node[i].weight);/*构造哈弗曼树*/for(i=0;i<n-1;i++){m1=m2=MAX;x1=x2=0;for(j=0;j<n+i;j++){if(huff_node[j].weight <m1&&huff_node[j].flag ==0){m2=m1;x2=x1;m1=huff_node[j].weight ;x1=j;}else if (huff_node[j].weight <m2&&huff_node[j].flag ==0) {m2=huff_node[j].weight;x2=j;}}huff_node[x1].parent=n+i;huff_node[x2].parent=n+i;huff_node[x1].flag =1;huff_node[x2].flag =1;huff_node[n+i].weight =huff_node[x1].weight +huff_node[x2].weight ; huff_node[n+i].lchild =x1;huff_node[n+i].rchild =x2;}/*求字符的哈弗曼编码*/for(i=0;i<n;i++){cd.start =n;c=i;p=huff_node[c].parent ;while(p!=0){if(huff_node[p].lchild ==c)cd.bits [cd.start ]=0;elsecd.bits [cd.start ]=1;cd.start=cd.start -1;c=p;p=huff_node[p].parent ;}cd.start ++;for(j=cd.start ;j<=n;j++)huff_code[i].bits[j]=cd.bits [j];huff_code[i].start =cd.start ;}/*输出字符的哈弗曼编码*/puts("the hafman code are:");for(i=0;i<n;i++){for(j=huff_code[i].start;j<=n;j++)printf("%10d",huff_code[i].bits [j]);printf("/n");}puts("press any key to quit...");}三、运行界面please input the leaf num of tree:8please input the weight of every leaf 1 2 3 4 5 6 7 1输出:11010 1100 100 101 1110001 11011。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
15
例:证明:一棵二叉树的前序序列和中序序 列可以唯一的确定这棵二叉树。
用归纳法证明: 1、当 n = 1时,结论显然成立; 2、假定当 n <= k 时,结论成立; 3、当 n = k + 1 时,假定前序序列为和中序序列 分别为: {a1,…,am} 和 {b1, … ,bm}
16
如 中 序 序 列 中 与 前 序 序 列 a1 相 同 的 元 素 为 b j 。 j =1时,二叉树无左子树,由 {a2,…,am} 和
先举例!
3
例1:设有4个字符d,i,a,n,出现的频度分别为7,5,2, 4,
怎样编码才能使它们组成的报文在网络中传得最快? 法1:等长编码。例如用二进制编码来实现。 取 d=00,i=01,a=10,n=11
法2:不等长编码,例如用哈夫曼编码来实现。 取 d=0; i=10, a=110, n=111 最快的编码是哪个?是非等长的Huffman码!
提示2:霍夫曼树的存储结构可采用顺序存储结构: 将整个霍夫曼树的结点存储在一个数组中:HT[1..n]; 将结点的编码存储在HC[1..n]中。 提示3:霍夫曼树如何构造?构造好之后又如何求得 各结点对应的霍夫曼编码?——算法参见教材P147。
参考 实验二补充材料中的方案二程序; 资料 喻信星空FTP网站上的“数据结构”演示程序
注:若圆满实现了此方案,平时成绩将以满分计。
字符 空格 频度 186 a 64 b 13 c 22 d 32
e
103
f 21
g 15
h 47
i 57
字符 频度
字符 频度
j 1
k 5
u 23
l 32
v 8
m 20
w 18
n 57
x 1
o 63
y 16
p 15
z 1
q 1
r 48
s 51
t
80
11
提示1:霍夫曼树中各结点的结构可以定义为如下 5个分量: char weight parent lchild Rchild
——将 Huffman树 与 Huffman编码
0 d 1
挂钩
0
i 0 a
1
1 n
Huffman编码结果:d=0, i=10, a=110, WPL=1bit×7+2bit×5+3bit(2+4)=35
n=111
特点:每一码都不是另一码的前缀,绝不会错译! 称为前缀码
6
霍夫曼编码的基本思想是:概率大的字符用短码,概率小的用 长码。由于霍夫曼树的WPL最小,说明编码所需要的比特数最 少。这种编码已广泛应用于网络通信中。
怎样实现Huffman编码?先要构造Huffman树!
4
构造Huffman树的步骤:
操作要点1:对权值的合并、删除与替换
——在权值集合{7,5,2,4}中,总是合并当前值最小的两个权
注:方框表示外结点(叶子,字符对应的权值), 圆框表示内结点(合并后的权值)。
5
操作要点2:按左0右1对Huffman树的所有分支编号!
6.5
Huffman树及其应用
b d e
a c f g
一、最优二叉树(霍夫曼树)
预备知识:若干术语 路 径: 由一结点到另一结点间的分支所构成
路径长度: 路径上的分支数目
a→e的路径长度= 2
树长度= 10 树的路径长度:从树根到每一结点的路径长度之和。 带权路径长度:结点到根的路径长度与结点上权的乘积 树中所有叶子结点的带权路径长度之和 树的带权路径长度: 霍 夫 曼 树: 带权路径长度最小的树。
解:先将概率放大100倍,以方便构造哈夫曼树。 权值集合 w={7, 19, 2, 6, 32, 3, 21, 10}, 按哈夫曼树构造规则(合并、删除、替换),可得到哈夫曼树。
7
为清晰起见,重新排序为: w={2, × 6, 7, 10, 19, 21, 32} × 3, w1={5, × 7, 10, 19, 21, 32} × 6, w2={7, 10, 11, 19, 21, 32} × × w3={11, 17, 19, 21, 32} × × w4={19, 21, 28, 32} × × w5={28,32,40} ×× w6={40,60} × × w7={100} 哈夫曼树 19 b
{b2, … ,bm} 可以唯一的确定二叉树的右子树;
j= m时,二叉树无右子树,由 {a2,…,am} 和
{b1, … ,bm-1} 可以唯一的确定二叉树的左子树;
如2<=j<=m-1,则子序列 {a2,…,aj} 和 {b1, …
,bj-1}唯一的确定二叉树的左子树;子序列{aj+1,
…,am} 和 {bj+1, … ,bm}唯一的确定二叉树的右
例2(严题集6.26③):假设用于通信的电文仅由8个字母
{a, b, c, d, e, f, g, h} 构成,它们在电文中出现的概率分别 为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10}, 试为这8个字母设计哈夫曼编码。如果用0~7的二进制编码方 案又如何?
子树
17
{a1,a2 , …,aj, aj+1, …,am}
个数相同
{b1,… ,bj-1,bj ,bj+1,… ,bm }
唯一的确定左子树
唯一的确定右子树
18
100
40
21 32 g e 17 7 a
60
28 11 10 h 6 d 2 c 5 3 f
8
对应的哈夫曼编码(左0右1):
符 编码 频率 符 编码 频率
100
a
b
1100
00
0.07
0.19
a
b
000
001
0.07
0 40
1
60 0 1 1 28 21 32 g e 0 1 17 11 0 1 0 1 5 7 10 6 a d 0 1 h 2 3 f c
1
Huffman树简介:
Weighted Path Length
树的带权路径长度如何计算? WPL = 哈夫曼树则是:WPL 最小的树。
w kl k
k=1
n
经典之例:
2 c 7 a 5 2 b c 4 d
Huffman树
7 a
4 d
7 a (b)
5 b
5 b
2 c (c)
4 d
(a)
WPL=36
12
二叉树小结
1、定义和性质 树
顺序结构
2、存储结构
链式结构
二叉链表
森林
二叉树
先序遍历
三叉链表
3、遍历
中序遍历
后序遍历
先序线索树
中序线索树
4、线索化:线索树 霍夫曼树
后序线索树
霍夫曼编码
13
附:中序遍历迭代算法(利用堆栈)
void iter_inorder(tree_pointer node) { int top= -1; /* initialize stack */ tree_pointer stack[MAX_STACK_SIZE]; for (;;) { for (; node; node=node->left_child) add(&top, node);/* add to stack */ node= delete(&top); /* delete from stack */ if (!node) break; /* empty stack */ printf(“%D”, node->data); node = node->right_child; } } 时间复杂度O(n)
=1.44+0.92+0.25=2.61
二进制码 WPL=3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3
9
另一26个英文字母,其出 现频度如下表所示。 要求编程实现: 先建哈夫曼树,再利用此树对报文“This program is my favorite”进行编码和译码。
14
附:层序遍历算法(利用队列)
void level_order(tree_pointer ptr) /* level order tree traversal */ { +*E*D /CAB int front = rear = 0; tree_pointer queue[MAX_QUEUE_SIZE]; if (!ptr) return; /* empty queue */ addq(front, &rear, ptr); for (;;) { ptr = deleteq(&front, rear);
WPL=46
WPL= 35
2
构造霍夫曼树的基本思想: 权值大的结点用短路径,权值小的结点用长路径。 构造Huffman树的步骤(即Huffman算法):
(1) 由给定的 n 个权值{w0, w1, w2, …, wn-1},构造具有 n 棵扩充 二叉树的森林F = { T0, T1, T2, …, Tn-1 },其中每一棵扩充二叉树 Ti 只有一个带有权值 wi 的根结点,其左、右子树均为空。 (2) 重复以下步骤, 直到 F 中仅剩下一棵树为止: ① 在 F 中选取两棵根结点的权值最小的扩充二叉树, 做为左、 右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为 其左、右子树上根结点的权值之和。 ② 在 F 中删去这两棵二叉树。 ③ 把新的二叉树加入 F。
c
d
11110
1110
0.02
0.06
相关文档
最新文档