| huffman 编码简介 |
| 在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(huffman)树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如jpeg中就应用了哈夫曼编码。 首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为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.71,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,当然你也可以反过来规定。 |
huffman 编码简介(讲解的更好一些,有c的分析)-.net教程,算法/线
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » huffman 编码简介(讲解的更好一些,有c的分析)-.net教程,算法/线
相关推荐
- 暂无文章
