加勒比海盗小提琴曲(双城变奏中的小提琴曲) 排球的场地如何安排及尺寸大小(排球比赛场地尺寸大小) 手机壳贴钻还能这样DIY 你不知道吧(怎样贴手机壳的钻才能更牢固) 余弦函数公式大全表格(余弦函数公式) 如何解决使用打印机突然提示“尚未安装打印机”(尚未安装打印机怎么回事) 梦幻西游三维版怎么联系在线客服(梦幻西游三维版客服电话人工服务电话) 销售原材料结转成本的会计分录(销售原材料会计分录) 手机如何查询东莞住房公积金?(手机如何查询东莞住房公积金贷款额度) 呆萌宠物对对碰攻略(萌宠对决攻略) 工程招标代理资质取消通知(工程招标代理资质) 法定节假日加班工资怎么算(法定节假加班工资怎么计算) 驾照理论考试技巧和方法(驾照理论考试技巧和方法口诀) 黄花菜不能和什么食物同吃(黄花菜不能和什么食物一起吃) HTC G12刷recovery教程及进入recovery方法(htc如何进入recovery) b血型的人有什么特点男(b血型的人有什么特点) Sai软件手绘简笔画绿色环保机器人(SAI画画软件) Their是什么意思中文翻译怎么读(their是什么意思) 网上赚钱创业方法大全(网上赚钱创业方法大全套) 走路赚钱的几种方式(走路赚钱的几种方式是什么) 红龙鱼饲养方法(红龙草) 怎样增强抵抗力(怎样增强抵抗力和免疫力) qb怎么转给别人(怎么把qb给别人) 不是花中偏爱菊此花开尽更无花全诗拼音(不是花中偏爱菊此花开尽更无花全诗) 微信新功能"拍一拍"上线!(微信新功能朋友圈折叠) 现场仪表HART通讯如何接线(hart怎么接线) peacewarfound的英语怎么读(peace war find怎么读) q版泡泡堂6怎么换人(q版泡泡堂可以三人吗) 如何获得更多渠道商及他们的支持(如何获得更多渠道商及他们的支持英语) 作文那一次我失败了(作文那一次我真高兴) 围巾情人扣的织法(围巾情人扣的织法粗线) 悬崖上的金鱼公主国语版樱花动漫(悬崖上的金鱼公主国语版高清) 智能电视怎么看地方台频道直播 教你方法(智能电视怎么看地方台的频道) 初二英语周报所有答案大全(初二英语周报答案网) 篮球计分器 教你使用篮球计分器!(篮球计分器如何使用) 玉兔怎么画简单又漂亮(玉兔怎么画简单又漂亮图片) 项目措施费包干含后期签证吗(项目措施费包括哪些) 像粑粑一样恶心人(像粑粑一样恶心人的图片) PPT如何修改激光笔颜色(放映ppt时激光笔的颜色是可以更改的) 果绿色cmyk色值为多少(果绿色cmyk色值) 淘宝天猫如何设置店铺抽奖?(淘宝天猫如何设置店铺抽奖时间) 怎么设置浏览器的兼容模式(怎么设置浏览器的兼容模式手机) 台达VFD-B 3.7kW变频器维修方法(台达vfd—b变频器使用手册) 摩尔庄园手游农庄拍照任务流程(摩尔庄园手游庄园拍照任务) 医者仁心的经典语录(医者仁心是什么意思) 打好台球的小技巧(打好台球的小技巧和方法) 纸张方向只设置一页横向(纸张种类) 京东巴枪联迪P990修改时间 红樱桃木门效果图(红樱桃木) 大梅沙附近酒店攻略(大梅沙附近住宿) 光纤猫 Modem)怎样设置无线上网?(光纤猫设置方法)
您的位置:首页 >综合精选 >

霍夫曼编码属于有损压缩(霍夫曼编码)

导读 关于霍夫曼编码属于有损压缩,霍夫曼编码这个问题很多朋友还不知道,今天小六来为大家解答以上的问题,现在让我们一起来看看吧!1、霍夫曼

关于霍夫曼编码属于有损压缩,霍夫曼编码这个问题很多朋友还不知道,今天小六来为大家解答以上的问题,现在让我们一起来看看吧!

1、霍夫曼编码是一种被广泛应用而且非常有效的数据压缩技术,根据待压缩数据的特征,一个可压缩掉20%~90%。

2、这里考虑的数据指的是字符串序列。

3、要理解霍夫曼编码,先要理解霍夫曼树,即最优二叉树,是一类带权路径长度最短的树。

4、路径是指从树中一个结点到另一个结点之间的通路,路径上的分支数目称为路径长度。

5、树的路径长度是从树根到每一个叶子之间的路径长度之和。

6、结点的带权路径长度为从该结点到树根之间的路径长度与该结点权的乘积,树的带权路径长度为树中所有叶子结点的带权路径长度之和.霍夫曼树是指所有叶子结点的二叉树中带权路径长度最小的二叉树.当给定了n个叶子结点的权值后,构造出的最优二叉树的结点数目m就确定了,即m=2n-1,所以可用一维结构树组来存储最优二叉树#define MAXLEAFNUM 50 /*最优二叉树中最大叶子树目*/struct node{ char ch; /*当前结点表示的字符,对于非叶子结点,此域不用*/ int weight; /*当前结点的权值*/ int parent; /*当前结点的父结点的下标,为0时表示无父结点*/ int lchild,rchild; /*当前结点的左,右孩子结点的下标,为0时表示无孩子结点*/}HuffmanTree[2 * MAXLEAFNUM];typedef char *HuffmanCode[MAXLEAFNUM + 1];创建最优二叉树void createHTree(HuffmanTree HT, char *c, int *w, int n){ /*数组c[0..n-1]和w[0..n-1]存放了n个字符及其概率,构造霍夫树HT*/ int i, s1, s2; if (n <= 1) return;/*根据n个权值构造n棵只有根结点的二叉树*/ for (i=1; i<=n; i++) { HT[i].ch = c[i-1]; HT[i].weight = w[i-1]; HT[i].parent = HT[i].lchild = HT[i].rchild = 0; }for (; i<2*n; ++i) { HT[i].parent = 0; HT[i].lchild = 0; HT[i].rchild = 0; }/*构造霍夫曼树*/ for (i=n+1; i<2*n; 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; }}应用霍夫曼编码假设有一个包含100 000个字符的数据文件要压缩存储。

7、各字符在该文件中的出现频度见表1。

8、仅有6种不同字符出现过,字符a出现了45000次。

9、 a b c d e f 频度(千字) 45 13 12 16 9 5固定代码字 000 001 010 011 100 101变长代码字 0 101 100 111 1101 1100表1 一个字符编码问题。

10、大小为100 000个字符的一个数据文件仅包含字符a~f,每个字符出现的频度如表中所示。

11、如果对每个字符赋予一个三位的编码,则该文件可被编码为300000位。

12、如果利用表中的可变长度编码,该文件可被编码为224000位。

13、可以用很多种方式来表示这样一个文件。

14、采用固定长度编码,则需要三位二进制数字来表示六个字符:a=000,b=001,…,f=101。

15、这种方法需要300 000来对整个原文件编码。

16、 而可变长度编码是对频度高的字符赋以短编码,而对频度低的字符赋以较长一些的编码。

17、表1显示了这种编码,其中一位串0表示a,四位串1100表示f。

18、这种编码方式需要 (45*1+13*3+12*3+16*3+9*4+5*4)*1000 = 224 000 位来表示整个文件,即可压缩掉约25%。

19、这其实就是最优字符编码(霍夫曼编码)前缀编码我们这里考虑的编码方案中,没有一个编码是另一个编码的前缀。

20、这样的编码称为前缀编码(或许“无前缀编码“是个更好的名字,但是前缀编码是标准的书面语)。

21、 对任何一种二进制字符编码来说编码总是简单的,这只要将文件中表示每个字符的编码并置起来即可。

22、利用表1的可变长度编码,把包含三个字符的文件abc编成0 . 101 . 100 = 0 101 100,其中“.“表示并置。

23、 在前缀编码中解码也是很方便的。

24、因为没有一个码是其他码的前缀,故被编码文件的开始处的编码是确定的。

25、我们只要识别出第一个编码,将它翻译成原文字符,再对余下的编码文件重复这个解码过程即可。

26、在我们的例子中,可将串001 011 101唯一地分析为0.0.101.1101,因此可解码为aabe。

27、 解码过程需要有一种关于前缀编码的方便表示,使得初始编码可以很容易地被识别出来。

28、有一种表示方法就是叶子为给定字符的二叉树。

29、在这种树中,我们将一个字符的编码解释为从根至该字符的路径,其中0表示“转向左子结点”,1表示“转向右子结点“。

30、如下给出最优二叉树,如图1。

31、图1以下给出查找最优二叉树叶子结点编码的算法typedef char *HuffmanCode[MAXLEAFNUM + 1];(本文开头也有说明)void HuffmanCoding(HuffmanTree HT, HuffmanCode HC, int n){ /* n个叶子结点在霍夫曼树HT中的下标为1~n,*/ /*第i(1<= i <= n)个叶子的编码存放HC[i]中*/ char *cd; int i,start,c,f; if (n<=1) return;/*分配n个字节的内存,用来存放当前得到的编码*/ /*n个叶子结点最大的编码长度为n所以分配n个字节*/ cd = (char*)malloc(n) 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) /*从叶子结点开始查找编码*/ /*叶子结点的父结点的左子树为叶子结点,则编码为0*/ /*否则就为父结点的右子树,则编码为1*/ if (HT[f].lchild = = c) cd[--start] = ‘0’; else cd[--start] = ‘1’; /*分配内存,分配内存的字节数为当前得到的字符编码数*/ HC[i] = (char*)malloc(n-start); strcpy(HC[i], &cd[start]);}free(cd);}译码算法为:从根结点出发,按二进制位串中的0和1确定是进入左分支还是右分支,当到达叶子结点时译出该叶子对应的字符。

32、数据文件(包含编码)未结束,则回到根结点继续进行上述过程。

33、给出如下函数:void Decoding(HuffmanTree HT, int n, char *buff){ /*利用具有n个叶子结点的最优二叉树(存储在数组HT中)进行译码,叶子的下标*//*为1~n,buff指向数据文件的编码序列*/int p = 2*n -1; /*指向根结点*/while (*buff){ if ((*buff) = = ‘0’) p = HT[p].lchild; /*进入左分支*/ else p = HT[p].rchild; /*进入右分支*//*到达一个叶子结点*/ if(HT[p].lchild = = 0 && HT[p].rchild = = 0) { printf(“%c”, HT[p].ch); p = 2*n – 1; /*回到根结点*/ }buff++;}}。

本文分享完毕,希望对大家有所帮助。

标签:

免责声明:本文由用户上传,如有侵权请联系删除!

最新文章