课程设计-哈夫曼编码的分析和实现

合集下载

哈夫曼编码的实现及应用

哈夫曼编码的实现及应用

哈夫曼编码的实现及应用哈夫曼编码(Huffman Coding)是一种用于数据压缩的编码技术,它可以将数据中频繁出现的字符或符号用较短的编码表示,从而减小数据的存储或传输开销。

以下是哈夫曼编码的实现和应用:实现哈夫曼编码:1. 构建哈夫曼树:首先,需要收集数据中不同字符或符号的频率信息,然后根据这些频率构建哈夫曼树。

在哈夫曼树中,频率较高的字符位于树的较低部分,频率较低的字符位于树的较高部分。

2. 分配编码:从根节点开始,沿着哈夫曼树的路径向下,为每个字符分配唯一的编码。

左子树通常表示0,右子树表示1。

这确保了编码是前缀编码,即没有一个编码是另一个编码的前缀。

3. 编码数据:使用分配的编码,将原始数据中的字符替换为相应的编码,从而生成压缩的数据。

哈夫曼编码的应用:1. 数据压缩:哈夫曼编码广泛用于数据压缩领域,包括压缩文件、图像、音频和视频数据。

由于频率较高的字符使用较短的编码,哈夫曼编码可以显著减小文件大小。

2. 通信系统:在通信系统中,数据通常需要在网络上传输。

使用哈夫曼编码可以减小数据传输的带宽要求,提高通信效率。

3. 文本编辑器:哈夫曼编码可用于实现字典压缩,减小文本文件的大小,使其更容易存储和传输。

4. 图像压缩:JPEG图片格式使用了哈夫曼编码来压缩图像数据,减小图像文件的大小。

5. 音频压缩:MP3音频格式中的音频数据也使用了哈夫曼编码,以减小音频文件的大小。

6. 存储设备:存储设备,如硬盘和闪存驱动器,通常使用哈夫曼编码来提高存储效率,减小数据的物理存储需求。

哈夫曼编码是一种有效的数据压缩方法,可以在多个领域中应用,以减小数据的大小并提高数据传输和存储的效率。

不同应用领域可能会采用不同的编码方式,但核心原理是一致的。

哈夫曼编码的设计与实现

哈夫曼编码的设计与实现

哈夫曼编码的设计与实现
哈夫曼编码是一种数据压缩算法,通过构建最小生成树来实现编码和解码操作。

下面是哈夫曼编码的设计和实现步骤:
1. 统计每个字符在文本中出现的频率。

2. 根据字符频率构建哈夫曼树:
a. 创建一个优先队列(最小堆),将每个字符的频率作为优先级。

b. 将每个字符作为一个单独的树节点,并插入优先队列中。

c. 重复以下步骤直到优先队列中只剩一个节点:
- 从优先队列中弹出两个频率最小的树节点。

- 创建一个新的树节点,将弹出的两个节点作为子节点,并将其频率之和作为新节点的频率。

- 将新节点插入优先队列中。

d. 最后一个剩下的节点即为哈夫曼树的根节点。

3. 构建字符和编码的映射表:
a. 从根节点出发,遍历哈夫曼树的所有路径。

b. 按照字符出现的顺序,记录每个字符对应的编码序列。

4. 对原文本进行编码:
a. 遍历原文本中的每个字符,根据映射表将其替换为对应的编码序列。

b. 将所有编码序列连接在一起,形成最终的编码结果。

5. 对编码结果进行解码:
a. 从哈夫曼树的根节点开始,遍历编码结果中的每个编码位。

b. 根据当前位的值,选择进入左子节点或右子节点。

c. 如果当前节点是叶子节点,则找到了一个字符,将其添加到解码结果中,并返回根节点继续解码。

d. 重复以上步骤直到遍历完整个编码结果。

6. 完成解码后,得到原始的文本内容。

以上是哈夫曼编码的设计和实现步骤,实际的实现可能需要使用递归、数据结构等相关知识。

数据结构 课程设计之哈夫曼编码

数据结构  课程设计之哈夫曼编码

(一) 哈夫曼树的设计思想对于一组具有确定权值的叶子结点可以构造出多个具有不同带权路径长度的二叉树,其中具有最小带权路径长度的二叉树称作哈夫曼树或者最优二叉树。

首先给定n 个权值创造n 个只含根结点的二叉树,得到一个二叉树林;再在这二叉树林里面找根结点的权值最小和次小的两棵树作成新的二叉树,其中新的二叉树的根结点的权值为摆布子根结点权值之和;最后在二叉树林中把组合过的二叉树删除,再重复第二步,直到最后就剩一颗二叉树的时候得到的这棵二叉树就是哈夫曼树。

(二)哈夫曼编码与解码的设计思想在数据通讯中,时常要将传送的文字转换为二进制字符0 和1 组成的二进制串,称这个过程为编码。

与子相对的是解码或者是译码,就是用与编码相同的方式将二进制串转换称编码前的文字的过程称作解码。

在这里是通过哈夫曼树实现编码与解码的,所以称作是哈夫曼编码与解码。

首先输入一个字符串,还有相应的在哈夫曼树里的权值,这样用哈夫曼树把字符串用二进制串代替它,这个过程要注意树和编码问题,其中树的问题在上面已经解决,主要看编码的问题,就是根据我们输入的字符串和权值建立相应的树模型,这一步完成那编码就已经完成为了,最后打印就行了;然后就是解码,完成编码相应的解码就相对简单了,就是先找到在编码的时候建的那个模型树,将编码中的二进制串再根据权值转换为相应的字符串,这样一步步解码就行了。

以上就是通过用哈夫曼树进行哈夫曼编码与解码如何实现的主要设计思想。

(一)哈夫曼树的流程图不 是图 1 哈夫曼树的流程图(二)编码与解码的流程图图 2 编码与解码的流程图图片说明: (左边)编码流程图, (右边)解码流程图。

开始输入字符串判断权值 建立路径有最小和次小 循环建立二叉树根据树对路径分左 0右 1写出对应结点的编码结束开始初始化哈夫曼链表二叉树林找最小和次小 的二叉树组合成新的二叉树 删除用过的二叉树是不是最后一 个二叉树是结束开始找到树的根结点 输入二进制串扫描根据树的路径打印对应字符继续扫描 是否结束是输出字符串结束否下面给出的是用中缀转后缀算法实现的程序的源代码:#include "stdio.h"#include "string.h"#define MAX 100struct HaffNode{int weight;int parent;char ch;int lchild;int rchild;}*myHaffTree;struct Coding{char bit[MAX];char ch;int weight;}*myHaffCode;void Haffman(int n){int i,j,x1,x2,s1,s2;for (i=n+1;i<=2*n-1;i++) {s1=s2=10000;x1=x2=0;for (j=1;j<=i-1;j++)/*定义常量*//*权值*//*双亲结点下标*//*构造哈夫曼树*//*定义数组*//*字符的权值*//*定义结构体*//*定义哈夫曼函数*//*树的初始化*//*构造哈夫曼树的非叶子结点*/{if(myHaffTree[j].parent==0&&myHaffTree[j].weight<s1){s2=s1;x2=x1;s1=myHaffTree[j].weight;x1=j;/*分配摆布结点*/}else if(myHaffTree[j].parent==0&&myHaffTree[j].weight<s2){s2=myHaffTree[j].weight;x2=j;}}myHaffTree[x1].parent=i;myHaffTree[x2].parent=i;myHaffTree[i].weight=s1+s2;myHaffTree[i].lchild=x1;myHaffTree[i].rchild=x2;/*摆布子组合为新树*/}}void HaffmanCode(int n){int start,c,f,i,j,k;char *cd;/*构造n 个结点哈夫曼编码*/cd=(char *)malloc(n*sizeof(char));myHaffCode=(struct Coding *)malloc((n+1)*sizeof(struct Coding));cd[n-1]='\0';for(i=1;i<=n;++i) /*n 个叶子结点的哈夫曼编码*/ {start=n-1;for(c=i,f=myHaffTree[i].parent;f!=0;c=f,f=myHaffTree[f].parent)if(myHaffTree[f].lchild==c) cd[--start]='0';else cd[--start]='1';for(j=start,k=0;j<n;j++){myHaffCode[i].bit[k]=cd[j];k++;}myHaffCode[i].ch=myHaffTree[i].ch; myHaffCode[i].weight=myHaffTree[i].weight; }free(cd);}Init(){int i,n,m;printf("please input the number of words:"); scanf("%d",&n); /*取编码对应的权值*//*定义有返回值的函数*/m=2*n-1;myHaffTree=(struct HaffNode *)malloc(sizeof(struct HaffNode)*(m+1)); for(i=1;i<=n;i++){printf("please input the word and the equal:");scanf("%s%d",&myHaffTree[i].ch,&myHaffTree[i].weight); myHaffTree[i].parent=0;myHaffTree[i].lchild=0;myHaffTree[i].rchild=0;}for(i=n+1;i<=m;i++){myHaffTree[i].ch ='#';myHaffTree[i].lchild=0;myHaffTree[i].parent=0;myHaffTree[i].rchild=0;myHaffTree[i].weight=0;}Haffman(n);HaffmanCode(n);for(i=1;i<=n;i++){printf("%c %d",myHaffCode[i].ch,myHaffCode[i].weight); printf("\n");}printf("init success!\n");return n;}void Caozuo_C(int m){int n,i,j;char string[50],*p;printf("please input the words :"); scanf("%s",string);n=strlen(string);for(i=1,p=string;i<=n;i++,p++){for(j=1;j<=m;j++)if(myHaffCode[j].ch==*p)printf("%s\n",myHaffCode[j].bit); }}void Caozuo_D(int n){int i,c;char code[1000],*p;printf("please input the coding:"); scanf("%s",code);for(p=code,c=2*n-1;*p!='\0';p++) {if(*p=='0'){c=myHaffTree[c].lchild;if(myHaffTree[c].lchild==0){printf("%c",myHaffTree[c].ch);c=2*n-1;continue;/* 编码函数*//*计算字符串长度*/ /*进行编码*//*解码函数*//*输入二进制编码*//*进行解码*//*结束条件*//*赋值*//* 扫描*//*结束*/}}else if(*p=='1'){c=myHaffTree[c].rchild;if(myHaffTree[c].lchild==0){printf("%c",myHaffTree[c].ch);c=2*n-1; /*赋值*/continue;}}}printf("\n");}void main(){int n;char char1;n=Init();printf("A.coding B.codeprintingwhile(1){scanf("%c",&char1);if(char1=='c')break;switch(char1){case'A':Caozuo_C(n);break;case'B':Caozuo_D(n);break;case'C':;break;}}}/*主函数*//*定义字符*//*函数的调用*/C.exit\nplease input the process:\n");/*判断字符*//*执行编码操作*//*执行解码操作*/哈夫曼编码与解码的实现(一)中缀转后缀算法的运行结果:这部份我主要遇到了如下三个问题,其内容与解决方法如下所列:问题1:刚开始不知道如何建一个好树,因为我开始试着建了几个二叉树,不知道什么原因运行的时候那编码总是不对,跟在草稿纸上自己画的那个二叉树总是不相符,就找原因。

数据结构 哈夫曼编码实验报告

数据结构 哈夫曼编码实验报告

数据结构哈夫曼编码实验报告数据结构哈夫曼编码实验报告1. 实验目的本实验旨在通过实践理解哈夫曼编码的原理和实现方法,加深对数据结构中树的理解,并掌握使用Python编写哈夫曼编码的能力。

2. 实验原理哈夫曼编码是一种用于无损数据压缩的算法,通过根据字符出现的频率构建一棵哈夫曼树,并根据哈夫曼树对应的编码。

根据哈夫曼树的特性,频率较低的字符具有较长的编码,而频率较高的字符具有较短的编码,从而实现了对数据的有效压缩。

实现哈夫曼编码的主要步骤如下:1. 统计输入文本中每个字符的频率。

2. 根据字符频率构建哈夫曼树,其中树的叶子节点代表字符,内部节点代表字符频率的累加。

3. 遍历哈夫曼树,根据左右子树的关系对应的哈夫曼编码。

4. 使用的哈夫曼编码对输入文本进行编码。

5. 将编码后的二进制数据保存到文件,同时保存用于解码的哈夫曼树结构。

6. 对编码后的文件进行解码,还原原始文本。

3. 实验过程3.1 统计字符频率首先,我们需要统计输入文本中每个字符出现的频率。

可以使用Python中的字典数据结构来记录字符频率。

遍历输入文本的每个字符,将字符添加到字典中,并递增相应字符频率的计数。

```pythondef count_frequency(text):frequency = {}for char in text:if char in frequency:frequency[char] += 1else:frequency[char] = 1return frequency```3.2 构建哈夫曼树根据字符频率构建哈夫曼树是哈夫曼编码的核心步骤。

我们可以使用最小堆(优先队列)来高效地构建哈夫曼树。

首先,将每个字符频率作为节点存储到最小堆中。

然后,从最小堆中取出频率最小的两个节点,将它们作为子树构建成一个新的节点,新节点的频率等于两个子节点频率的和。

将新节点重新插入最小堆,并重复该过程,直到最小堆中只剩下一个节点,即哈夫曼树的根节点。

(完整word版)数据结构课程设计(哈夫曼编码)

(完整word版)数据结构课程设计(哈夫曼编码)

目录目录 (1)1 课程设计的目的和意义 (3)2 需求分析 (5)3 系统设计 (6)(1)设计思路及方案 (6)(2)模块的设计及介绍 (6)(3)主要模块程序流程图 (9)4 系统实现 (14)(1)主调函数 (14)(2)建立HuffmanTree (14)(3)生成Huffman编码并写入文件 (18)(4)电文译码 (19)5 系统调试 (22)小结 (25)参考文献 (26)附录源程序 (27)1 课程设计的目的和意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。

哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。

树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0"码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1"的序列作为和各个对应的字符的编码,这就是哈夫曼编码。

通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。

电报通信是传递文字的二进制码形式的字符串。

但在信息传递时,总希望总长度尽可能最短,即采用最短码。

作为软件工程专业的学生,我们应该很好的掌握这门技术。

在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。

在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。

这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。

在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。

更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见.同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。

数据结构课程设计哈夫曼编码

数据结构课程设计哈夫曼编码

数据结构与算法学号:2012141441210 姓名:张敏数据结构与算法实验报告一、题目--赫夫曼编码/译码器1. 问题描述利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。

对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

试为这样的信息收发站编写一个赫夫曼码的编/译码系统。

2.基本要求一个完整的系统应具有以下功能:(1) I:初始化(Initialization)。

从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。

(2) E:编码(Encoding)。

利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。

(3) D:译码(Decoding)。

利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。

以下为选做:(4) P:印代码文件(Print)。

将文件CodeFile以紧凑格式显示在终端上,每行50个代码。

同时将此字符形式的编码文件写入文件CodePrin中。

(5) T:印赫夫曼树(Tree printing)。

将已在内存中的赫夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的赫夫曼树写入文件TreePrint 中。

3.测试要求(1) 已知某系统在通信联络中只可能出现八种字符,其频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计赫夫曼编码。

(2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“THIS PROGRAME IS MY FA VORITE”。

字符 A B C D E F G H I J K L M频度186 64 13 22 32 103 21 15 47 57 1 5 32 20字符N O P Q R S T U V W X Y Z频度57 63 15 1 48 51 80 23 8 18 1 16 14.实现提示(1) 编码结果以文本方式存储在文件Codefile中。

哈夫曼编码的课设心得

哈夫曼编码的课设心得

哈夫曼编码的课设心得
哈夫曼编码,这门课程设计,让我对数据压缩和编码有了更深入的理解。

在此之前,我对编码的了解仅限于基本的ASCII码,但通过这次学习,我发现编码的世界远比我想象的复杂且有趣。

哈夫曼编码是一种非常有效的数据压缩算法,它利用了数据的概率分布特性,为出现频率高的数据分配较短的编码,而出现频率低的数据则分配较长的编码。

这样,在总体上,数据就被有效地压缩了。

学习哈夫曼编码的过程中,我首先了解了其基本原理,然后通过编程实现了一个简单的哈夫曼编码器。

在实现过程中,我遇到了许多困难。

例如,如何有效地构建哈夫曼树,如何进行编码和解码等等。

通过不断地尝试和调整,我逐渐掌握了这些技巧。

同时,我也深刻体会到了算法和数据结构的重要性。

哈夫曼编码的实现需要我们熟练掌握二叉树、优先队列等数据结构和相关的算法。

此外,这次课程设计也让我认识到了团队合作的重要性。

在完成项目的过程中,我和我的团队成员经常一起讨论、交流,共同解决问题。

这种合作精神不仅让我们顺利完成了项目,也让我学到了很多与人沟通和协作的技巧。

总的来说,这次哈夫曼编码的课程设计让我收获颇丰。

我不仅学到了许多关于编码的知识,还锻炼了自己的编程能力和团队协作能力。

我相信这些经验将对我未来的学习和工作产生积极的影响。

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版下面是哈夫曼编码算法的完整实现。

1.统计字符频率首先,我们需要统计待压缩的文本中每个字符出现的频率。

遍历文本文件,统计每个字符的出现次数。

将字符和对应的频率存储在一个频率表中。

2.构建哈夫曼树接下来,我们使用统计得到的频率表构建哈夫曼树。

哈夫曼树是一种二叉树,每个内部节点都有两个子节点,分别代表0和1首先,将频率表中的每个字符作为叶子节点,并按照频率从小到大进行排序。

然后,依次选择频率最小的两个节点,将它们作为子节点创建一个新的节点,并将新节点的频率设置为这两个节点频率之和。

将新节点插入到频率表中,然后删除原来的两个节点。

重复上述步骤,直到频率表中只剩下一个节点,即哈夫曼树的根节点。

3.生成编码表根据构建好的哈夫曼树,我们可以生成字符的编码表。

遍历哈夫曼树,记录从根节点到每个叶子节点的路径,其中0代表左子节点,1代表右子节点。

4.压缩数据通过编码表,我们可以将原始数据进行压缩。

遍历原始文本,将每个字符替换为对应的编码,然后将所有编码拼接成一个二进制字符串。

5.存储压缩后的数据将压缩后的二进制字符串进行存储,可以使用二进制文件或者文本文件存储。

6.解压数据对于解压,我们需要加载压缩后的数据,并重新构建哈夫曼树。

遍历压缩后的二进制字符串,根据哈夫曼树的结构逐个读取二进制位,当遇到叶子节点时,输出对应的字符。

通过上述步骤,我们可以实现对文本数据的压缩和解压。

需要注意的是,由于哈夫曼编码是基于字符频率进行优化的,所以对于不同的文本文件,编码效果也会有所不同。

较为重复的字符出现频率高的文本文件,哈夫曼编码效果会更好。

哈夫曼实验报告

哈夫曼实验报告

一、实验目的1. 理解哈夫曼编码的基本原理和重要性。

2. 掌握哈夫曼树的构建方法。

3. 熟悉哈夫曼编码和译码的实现过程。

4. 分析哈夫曼编码在数据压缩中的应用效果。

二、实验原理哈夫曼编码是一种基于字符频率的编码方法,它利用字符出现的频率来构造一棵最优二叉树(哈夫曼树),并根据该树生成字符的编码。

在哈夫曼树中,频率越高的字符对应的编码越短,频率越低的字符对应的编码越长。

这样,对于出现频率较高的字符,编码后的数据长度更短,从而实现数据压缩。

三、实验内容1. 构建哈夫曼树:- 统计待编码数据中每个字符出现的频率。

- 根据字符频率构建哈夫曼树,其中频率高的字符作为叶子节点,频率低的字符作为内部节点。

- 重复上述步骤,直到树中只剩下一个节点,即为哈夫曼树的根节点。

2. 生成哈夫曼编码:- 从哈夫曼树的根节点开始,对每个节点进行遍历,根据遍历方向(左子树为0,右子树为1)为字符分配编码。

- 将生成的编码存储在编码表中。

3. 编码和译码:- 使用生成的编码表对原始数据进行编码,将编码后的数据存储在文件中。

- 从文件中读取编码后的数据,根据编码表进行译码,恢复原始数据。

四、实验步骤1. 编写代码实现哈夫曼树的构建:- 定义节点结构体,包含字符、频率、左子树、右子树等属性。

- 实现构建哈夫曼树的核心算法,包括节点合并、插入等操作。

2. 实现编码和译码功能:- 根据哈夫曼树生成编码表。

- 编写编码函数,根据编码表对数据进行编码。

- 编写译码函数,根据编码表对数据进行译码。

3. 测试实验效果:- 选择一段文本数据,使用实验代码进行编码和译码。

- 比较编码前后数据的长度,分析哈夫曼编码的压缩效果。

五、实验结果与分析1. 哈夫曼树构建:- 成功构建了哈夫曼树,树中节点按照字符频率从高到低排列。

2. 哈夫曼编码:- 成功生成编码表,字符与编码的对应关系符合哈夫曼编码原理。

3. 编码与译码:- 成功实现编码和译码功能,编码后的数据长度明显缩短,译码结果与原始数据完全一致。

哈夫曼编码实验报告心得

哈夫曼编码实验报告心得

哈夫曼编码实验报告心得简介哈夫曼编码是一种用于数据压缩的算法,在信息论和编码理论中扮演着重要的角色。

它基于将出现频率较高的字符用较短的二进制编码表示,而将较少出现的字符用较长的二进制编码表示,从而达到压缩数据的目的。

在这次实验中,我对哈夫曼编码进行了深入的学习和实践,并对其进行了评估和测试。

通过实验,我对哈夫曼编码有了更深入的了解,并收获了一些宝贵的心得体会。

实验过程步骤一:构建哈夫曼树首先,我需要根据给定的数据集构建哈夫曼树。

在构建哈夫曼树的过程中,我采用了优先队列来保存节点,每次选择权重最小的节点进行合并,直到最终合并成一棵完整的哈夫曼树。

步骤二:生成编码表构建好哈夫曼树之后,我需要根据这棵树生成每个字符对应的二进制编码。

这一步需要按照哈夫曼树的路径从根节点到叶子节点进行遍历,每经过一条左子树的路径,就加上一个0,每经过一条右子树的路径,就加上一个1,直到达到叶子节点为止。

步骤三:进行编码压缩生成编码表之后,我根据编码表对原始数据进行了编码压缩。

将每个字符通过其对应的二进制编码进行替换,得到了压缩后的数据。

步骤四:进行解码还原最后,我对压缩后的数据进行解码还原。

通过对编码表的反向查找,将二进制编码转换为原始字符,得到了还原后的数据。

心得体会通过这次实验,我对哈夫曼编码有了更深入的了解。

一开始我遇到了一些困难,例如如何构建哈夫曼树和生成编码表,但通过查阅相关资料和和老师的指导,我逐渐掌握了相关的知识和技巧。

实验中,我发现哈夫曼编码在压缩数据方面有着很好的效果。

根据实验结果,使用哈夫曼编码可以将原始数据压缩到原来的约50%左右,这对于节省存储空间和加快数据传输速度都有着重要的意义。

另外,在实验过程中,我也意识到了哈夫曼编码的一些局限性。

由于是根据字符出现的频率进行编码,在处理一些重复的字符时,哈夫曼编码的压缩效果并不理想。

此外,哈夫曼编码的编解码速度受到哈夫曼树的构建和编码表的生成等步骤的影响,对于大规模数据的处理并不高效。

哈夫曼编码 实验报告

哈夫曼编码 实验报告

哈夫曼编码实验报告哈夫曼编码实验报告一、引言哈夫曼编码是一种用于数据压缩的算法,由大卫·哈夫曼于1952年提出。

它通过将出现频率高的字符用较短的编码表示,从而实现对数据的高效压缩。

本实验旨在通过实际操作和数据分析,深入了解哈夫曼编码的原理和应用。

二、实验目的1. 掌握哈夫曼编码的基本原理和算法;2. 实现哈夫曼编码的压缩和解压缩功能;3. 分析不同数据集上的压缩效果,并对结果进行评估。

三、实验过程1. 数据集准备本实验选取了三个不同的数据集,分别是一篇英文文章、一段中文文本和一段二进制数据。

这三个数据集具有不同的特点,可以用来评估哈夫曼编码在不同类型数据上的压缩效果。

2. 哈夫曼编码实现在实验中,我们使用了Python编程语言来实现哈夫曼编码的压缩和解压缩功能。

首先,我们需要统计数据集中各个字符的出现频率,并构建哈夫曼树。

然后,根据哈夫曼树生成每个字符的编码表,将原始数据转换为对应的编码。

最后,将编码后的数据存储为二进制文件,并记录编码表和原始数据的长度。

3. 压缩效果评估对于每个数据集,我们比较了原始数据和压缩后数据的大小差异,并计算了压缩比和压缩率。

压缩比是指压缩后数据的大小与原始数据大小的比值,压缩率是指压缩比乘以100%。

通过对比不同数据集上的压缩效果,我们可以评估哈夫曼编码在不同类型数据上的性能。

四、实验结果与分析1. 英文文章数据集对于一篇英文文章,经过哈夫曼编码压缩后,我们发现压缩比为0.6,即压缩后的数据只有原始数据的60%大小。

这说明哈夫曼编码在英文文本上具有较好的压缩效果。

原因在于英文文章中存在大量的重复字符,而哈夫曼编码能够利用字符的出现频率进行编码,从而减少数据的存储空间。

2. 中文文本数据集对于一段中文文本,我们发现哈夫曼编码的压缩效果不如在英文文章上的效果明显。

压缩比为0.8,即压缩后的数据只有原始数据的80%大小。

这是因为中文文本中的字符种类较多,并且出现频率相对均匀,导致哈夫曼编码的优势减弱。

哈夫曼编码详解(C语言实现)

哈夫曼编码详解(C语言实现)

哈夫曼编码详解(C语言实现)哈夫曼编码是一种常见的前缀编码方式,被广泛应用于数据压缩和传输中。

它是由大卫·哈夫曼(David A. Huffman)于1952年提出的,用于通过将不同的字符映射到不同长度的二进制码来实现数据的高效编码和解码。

1.统计字符频率:遍历待编码的文本,记录每个字符出现的频率。

2.构建哈夫曼树:根据字符频率构建哈夫曼树,其中出现频率越高的字符位于树的较低层,频率越低的字符位于树的较高层。

3.生成编码表:从哈夫曼树的根节点开始,遍历哈夫曼树的每个节点,为每个字符生成对应的编码。

在遍历过程中,从根节点到叶子节点的路径上的“0”表示向左,路径上的“1”表示向右。

4.进行编码:根据生成的编码表,将待编码的文本中的每个字符替换为对应的编码。

5.进行解码:根据生成的编码表和编码结果,将编码替换为原始字符。

下面是一个用C语言实现的简单哈夫曼编码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>//定义哈夫曼树的节点结构体typedef struct HuffmanNodechar data; // 字符数据int freq; // 字符出现的频率struct HuffmanNode *left; // 左子节点struct HuffmanNode *right; // 右子节点} HuffmanNode;//定义编码表typedef structchar data; // 字符数据char *code; // 字符对应的编码} HuffmanCode;//统计字符频率int *countFrequency(char *text)int *frequency = (int *)calloc(256, sizeof(int)); int len = strlen(text);for (int i = 0; i < len; i++)frequency[(int)text[i]]++;}return frequency;//创建哈夫曼树HuffmanNode *createHuffmanTree(int *frequency)//初始化叶子节点HuffmanNode **leaves = (HuffmanNode **)malloc(256 * sizeof(HuffmanNode *));for (int i = 0; i < 256; i++)if (frequency[i] > 0)HuffmanNode *leaf = (HuffmanNode*)malloc(sizeof(HuffmanNode));leaf->data = (char)i;leaf->freq = frequency[i];leaf->left = NULL;leaf->right = NULL;leaves[i] = leaf;} elseleaves[i] = NULL;}}//构建哈夫曼树while (1)int min1 = -1, min2 = -1;for (int i = 0; i < 256; i++)if (leaves[i] != NULL)if (min1 == -1 , leaves[i]->freq < leaves[min1]->freq) min2 = min1;min1 = i;} else if (min2 == -1 , leaves[i]->freq < leaves[min2]->freq)min2 = i;}}}if (min2 == -1)break;}HuffmanNode *parent = (HuffmanNode*)malloc(sizeof(HuffmanNode));parent->data = 0;parent->freq = leaves[min1]->freq + leaves[min2]->freq;parent->left = leaves[min1];parent->right = leaves[min2];leaves[min1] = parent;leaves[min2] = NULL;}HuffmanNode *root = leaves[min1];free(leaves);return root;//生成编码表void generateHuffmanCode(HuffmanNode *root, HuffmanCode *huffmanCode, char *code, int depth)if (root->left == NULL && root->right == NULL)code[depth] = '\0';huffmanCode[root->data].data = root->data;huffmanCode[root->data].code = strdup(code);return;}if (root->left != NULL)code[depth] = '0';generateHuffmanCode(root->left, huffmanCode, code, depth + 1);}if (root->right != NULL)code[depth] = '1';generateHuffmanCode(root->right, huffmanCode, code, depth + 1);}//进行编码char *encodeText(char *text, HuffmanCode *huffmanCode)int len = strlen(text);int codeLen = 0;char *code = (char *)malloc(len * 8 * sizeof(char));for (int i = 0; i < len; i++)strcat(code + codeLen, huffmanCode[(int)text[i]].code);codeLen += strlen(huffmanCode[(int)text[i]].code);}return code;//进行解码char* decodeText(char* code, HuffmanNode* root) int len = strlen(code);char* text = (char*)malloc(len * sizeof(char)); int textLen = 0;HuffmanNode* node = root;for (int i = 0; i < len; i++)if (code[i] == '0')node = node->left;} elsenode = node->right;}if (node->left == NULL && node->right == NULL) text[textLen] = node->data;textLen++;node = root;}}text[textLen] = '\0';return text;int maichar *text = "Hello, World!";int *frequency = countFrequency(text);HuffmanNode *root = createHuffmanTree(frequency);HuffmanCode *huffmanCode = (HuffmanCode *)malloc(256 * sizeof(HuffmanCode));char code[256];generateHuffmanCode(root, huffmanCode, code, 0);char *encodedText = encodeText(text, huffmanCode);char *decodedText = decodeText(encodedText, root);printf("Original Text: %s\n", text);printf("Encoded Text: %s\n", encodedText);printf("Decoded Text: %s\n", decodedText);//释放内存free(frequency);free(root);for (int i = 0; i < 256; i++)if (huffmanCode[i].code != NULL)free(huffmanCode[i].code);}}free(huffmanCode);free(encodedText);free(decodedText);return 0;```上述的示例代码实现了一个简单的哈夫曼编码和解码过程。

哈夫曼编码的设计与实现1

哈夫曼编码的设计与实现1

华北科技学院计算机学院开放实验实验报告实验名称哈夫曼树编码的设计与实现实验学期2014 至2015 学年第一学期学生所在系部计算机学院年级2013 专业班级软件工程B13-2班学生姓名扈鹏程学号201307044213任课教师栾尚敏实验成绩计算机学院制《哈夫曼树编码的设计与实现》开放实验报告主程序模块开始1、初始化2、修改字符修改初始编码字符初始化哈夫曼链表1、建树2、修改字符建立哈夫曼树修改初始编码字符操作选择退出编 码译 码打印哈夫曼树1、继续2、返回上层3、退出结束1212332查看字符编码修改初始编码字符点代替原来两个结点的位置,其权值为两个子结点的权值只和,然后回到开始的判断。

判断文件指针是否为结束标记打开文件读取一个字符C==P->C || P==NULL 否P=P->NEXT是C==P->CP->W++新建结点存储字符,并赋权值为1关闭文件是否仅剩下1个结点是指针指向头p=head否判断是否是为回车获取一个字符串中存储的编码。

再次读取一个字符回到判断处,进行循环。

判断是否有字符是否存在左子树输出字符处理右子树处理左子树是否存在右子树是是输入要编码的字符c == p->c 输出该字符c == p->c 存的编码C!=’\n ’是否译码 输出错误字符并重新获取字符C !=‘0’|| C !=‘1’1、C !=‘0’2、 C !=‘1’P=head 输入译码字符P=P->lchildP=P->rchildC!=’\n ’P->c !=‘\0’输出p->c P=head获取译码字符否否是12是否①。

信息论与编码课程设计(哈夫曼编码的分析与实现)

信息论与编码课程设计(哈夫曼编码的分析与实现)

吉林建筑大学电气与电子信息工程学院信息理论与编码课程设计报告设计题目:哈夫曼编码的分析与实现专业班级:电子信息工程101学生姓名:学号:指导教师:吕卅王超设计时间:2013.11.18-2013.11.29一、设计的作用、目的《信息论与编码》是一门理论与实践密切结合的课程,课程设计是其实践性教学环节之一,同时也是对课堂所学理论知识的巩固和补充。

其主要目的是加深对理论知识的理解,掌握查阅有关资料的技能,提高实践技能,培养独立分析问题、解决问题及实际应用的能力。

通过完成具体编码算法的程序设计和调试工作,提高编程能力,深刻理解信源编码、信道编译码的基本思想和目的,掌握编码的基本原理与编码过程,增强逻辑思维能力,培养和提高自学能力以及综合运用所学理论知识去分析解决实际问题的能力,逐步熟悉开展科学实践的程序和方法二、设计任务及要求通过课程设计各环节的实践,应使学生达到如下要求:1. 理解无失真信源编码的理论基础,掌握无失真信源编码的基本方法;2. 掌握哈夫曼编码/费诺编码方法的基本步骤及优缺点;3. 深刻理解信道编码的基本思想与目的,理解线性分组码的基本原理与编码过程;4. 能够使用MATLAB 或其他语言进行编程,编写的函数要有通用性。

三、设计内容一个有8个符号的信源X ,各个符号出现的概率为:编码方法:先将信源符号按其出现的概率大小依次排列,并取概率最小的字母分别配以0和1两个码元(先0后1或者先1后0,以后赋值固定),再将这两个概率相加作为一个新字母的概率,与未分配的二进制符号的字母重新排队。

并不断重复这一过程,直到最后两个符号配以0和1为止。

最后从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即为对应的码字。

哈夫曼编码方式得到的码并非唯一的。

在对信源缩减时,两个概率最小的符号合并后的概率与其他信源符号的概率相同时,这两者在缩减中的排序将会导致不同码字,但不同的排序将会影响码字的长度,一般讲合并的概率放在上面,12345678,,,,,()0.40.180.10.10.070.060.050.04X x x x x x x x x P X ⎡⎤⎧⎫=⎨⎬⎢⎥⎣⎦⎩⎭这样可获得较小的码方差。

哈夫曼编码的实现及应用

哈夫曼编码的实现及应用

哈夫曼编码的实现及应用哈夫曼编码是一种可变长度编码的方法,它是由大名鼎鼎的美国数学家大卫·哈夫曼(David Huffman)于1952年提出的,用于有效地压缩数据。

在哈夫曼编码中,出现频率较高的字符被赋予较短的编码,而出现频率较低的字符则被赋予较长的编码,以达到尽可能减少编码长度的目的。

下面将在实现和应用这两个方面详细介绍哈夫曼编码。

首先是哈夫曼编码的实现。

哈夫曼编码的实现过程可以分为两个主要步骤:构建哈夫曼树和生成编码表。

构建哈夫曼树的步骤如下:1.统计待编码的字符出现的频次,并根据频次构建一个包含这些字符的节点集合。

2.从节点集合中选取频次最小的两个节点,合并成一个新节点,频次为这两个节点的频次之和,并将新节点加入节点集合中。

3.重复上述步骤,直到节点集合中只剩下一个节点,即为哈夫曼树的根节点。

生成编码表的步骤如下:1.从哈夫曼树的根节点开始,按照左子树标记0、右子树标记1的规则,遍历树的每个节点。

2.当遇到叶子节点时,将节点的字符与路径上的标记组合成该字符的哈夫曼编码,并将字符与编码添加到编码表中。

3.继续遍历树的下一个节点,直到所有节点都被遍历完。

在实现哈夫曼编码时,可以使用优先队列(例如最小堆)来选择频次最小的节点,以提高效率。

接下来是哈夫曼编码的应用。

哈夫曼编码在数据压缩领域有着广泛的应用。

以文本文件为例,由于文本中一些字符出现的频率较高,而另一些字符出现的频率较低,使用固定长度编码(如ASCII码)来存储文本会浪费存储空间。

而利用哈夫曼编码可以将频次较高的字符用较短的编码来表示,从而实现数据的压缩。

另外,哈夫曼编码也被用于网络传输数据的压缩。

在网络传输中,数据量大、传输速率有限,因此需要将数据进行压缩以减少传输时间和带宽占用。

通过使用哈夫曼编码,可以将数据进行压缩后再传输,接收端再进行解码还原为原始数据。

这样既减小了传输数据的大小,又提高了传输效率。

此外,哈夫曼编码还被广泛应用于图像和音频等多媒体数据的压缩。

数据结构课程设计哈夫曼编码

数据结构课程设计哈夫曼编码

《数据结构与算法》课程设计(2009/2010学年第二学期第20周)指导教师:***班级:计算机科学与技术(3)班学号:姓名:《数据结构与算法》课程设计目录一、前言1.摘要2.《数据结构与算法》课程设计任务书二、实验目的三、题目--赫夫曼编码/译码器1.问题描述2.基本要求3.测试要求4.实现提示四、需求分析--具体要求五、概要设计六、程序说明七、详细设计八、实验心得与体会前言1.摘要随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。

算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。

算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。

数据结构是在整个计算机科学与技术领域上广泛被使用的术语。

它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。

数据结构有逻辑上的数据结构和物理上的数据结构之分。

逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。

数据结构是数据存在的形式。

《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。

数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。

学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。

通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。

2.《数据结构与算法》课程设计任务书《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。

哈夫曼树编码实验报告

哈夫曼树编码实验报告

哈夫曼树编码实验报告、数据结构课程设计报告题目:哈夫曼编码/译码学院数学与信息科学学院学科门类理科专业数学类学号2013433033姓名田娟2014年12 月30日目录一、需求分析1.程序的功能 (3)2.输入输出的要求 (3)3.测试数据 (3)二、概要设计1.本程序所用的抽象数据类型的定义 (3)2.主程序模块 (3)3.主模块的流程及各子模块的主要功能 (4)4.模块之间的层次关系 (4)三、详细设计1.采用c语言定义相关的数据类型 (4)2. 伪码算法 (5)四、调试分析1.调试中遇到的问题及对问题的解决方法 (15)五、使用说明及测试结果1.建立哈夫曼树,输入叶子结点个数,权值,字符集 (15)2.编码 (15)3.译码 (16)4.显示码文 (16)5.显示哈夫曼树 (16)六、源程序一、需求分析1.程序的功能;哈夫曼编码是一种应用广泛而有效的数据压缩技术。

利用哈夫曼编码进行通信可以大大提高信道利用率,加快信息传输速度,降低传输成本。

数据压缩的过程称为编码,解压缩的过程称为译码。

进行信息传递时,发送端通过一个编码系统对待传数据(明文)预先编码,而接收端将传来的数据(密文)进行译码。

2.输入输出的要求;:2.1.构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权值,建立哈夫曼树;利用已经建好的哈夫曼树求每个叶结点的哈夫曼编码,并保存。

2.2编码:利用已构造的哈夫曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。

2.3.译码:将“密文”文件中的0、1代码序列进行译码。

2.4.打印“密文”文件:将文件以紧凑格式显示在终端上,每行30个代码;同时,将此字符形式的编码文件保存。

2.5.打印哈夫曼树及哈夫曼编码:将已在内存中的哈夫曼树以凹入表形式显示在终端上,同时将每个字符的哈夫曼编码显示出来;并保存到文件。

3.测试数据。

3.1.令叶子结点个数N为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。

数据结构课程设计-哈夫曼编码实验报告

数据结构课程设计-哈夫曼编码实验报告

数据结构课程设计报告实验二哈夫曼编码目录一.问题描述及分析p11.问题描述p12.需求分析p1 二.功能模块及数据结构描述p11.数据结构描述 p1 2.模块描述 p2三.主要算法流程描述p21.编码流程图 p3 2.译码流程图 p4四.使用说明p5 五.调试分析说明p6一.问题描述及分析1.问题描述设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件(后缀名.cod);反过来,可将一个编码文件还原为一个文本文件(.txt)。

2.需求分析(1)输入一个待压缩的文本文件名,统计文本文件中各字符的个数作为权值,生成哈夫曼树;(2)将文本文件利用哈夫曼树进行编码,生成编码文件(后缀名cod);(3)输入一个待解压的压缩文件名称,并利用相应的哈夫曼树将编码序列译码;(4)显示指定的编码文件和文本文件;3.运行要求.Windows xp/2003.VC++6.0(或以上)运行库二.功能模块及数据结构描述1.数据结构描述typedef struct{long weight;long lchild,rchild,parent;}hfmt;hfmt t[2*256-1];存放哈夫曼树结构体,weight为节点权值,lchild,rchild为节点的左右孩子在向量中的下标(为叶节点时,两值为:-1),parent为节点的双亲在向量中的下标(用来区别根与非根节点,值为-1与非-1)。

typedef struct{char bits[256];long s;}hfmcc;hfmcc cc[256];存放哈夫曼编码结构体,s用来指示编码在位串bits[n]中的起始位置。

2.模块描述图2.1 系统函数copy函数:根据s的值在位串bits[n]中提取有效编码位数。

HFM函数:对读入的节点权值,生成哈夫曼树。

HFMBM函数:对生成的哈夫曼树进行零一编码,对应于原文件字符。

三.主要算法流程描述1.编码流程图图2.2 编码流程图2.译码流程图图2.3 译码流程图四.使用说明图2.4 生成的文件本软件默认生成的编码文件名为:a.cod默认生成的译码文件名为:b.txt执行提示:输入所要编码的文本文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计任务书2010—2011学年第一学期专业:通信工程学号:070110101 姓名:苟孟洛课程设计名称:信息论与编码课程设计设计题目:哈夫曼编码的分析与实现完成期限:自2010 年12月20 日至2010 年12 月26 日共1 周一.设计目的1、深刻理解信源编码的基本思想与目的;2、理解哈夫曼编码方法的基本过程与特点;3、提高综合运用所学理论知识独立分析和解决问题的能力;4、使用MATLAB或其他语言进行编程。

二.设计内容假设已知一个信源的各符号概率,编写适当函数,对其进行哈夫曼编码,得出码字,平均码长和编码效率,总结此编码方法的特点和应用。

三.设计要求1、编写的函数要有通用性;2、信源可以自由选择,符号信源与图像信源均可。

四.设计条件计算机、MATLAB或其他语言环境五、参考资料[1]曹雪虹,张宗橙.信息论与编码.北京:清华大学出版社,2007.[2]王慧琴.数字图像处理.北京:北京邮电大学出版社,2007.指导教师(签字):教研室主任(签字):批准日期:年月日摘要哈夫曼编码(Huffman Coding)是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。

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

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

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

本课题通过MATLAB编写适当的函数,对一个随机信源进行哈夫曼编码,得出码字,平均码长和编码效率。

从而理解信源编码的基本思想与目的以及哈夫曼编码方法的基本过程与特点,并且提高综合运用所学理论知识独立分析和解决问题的能力。

关键字:哈夫曼,信源编码,MATLAB目录1 课题描述.................................................................................. 错误!未定义书签。

2 哈夫曼编码的原理................................................................. .错误!未定义书签。

2.1哈夫曼编码的构造过程 (1)2.2哈夫曼编码的应用举例 (1)3 哈夫曼编码的实现过程 (4)3.1 软件介绍 (4)3.2设计内容 (4)3.2设计步骤 (4)4 程序运行结果分析 (8)总结 (10)参考文献 (11)1课题描述哈夫曼编码是一种编码方式,以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。

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

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

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

2哈夫曼编码的原理2.1 哈夫曼编码的构造过程实现哈夫曼算法的大致描述为:初始化:将2n-1个结点的三个指针域的值置为空(可用-1表示),权值为0;输入:读入n个叶结点的权值存入向量的前个分量中,即形成有个结点的森林(一个结点为一棵树);排序:按权值排序(从小到大)合并:把前两棵树组成一棵新树,放回森林,直至形成一棵树最后输出哈夫曼编码2.2哈夫曼编码应用举例哈夫曼树被广泛的应用在各种技术中,其中最典型的就是在编码技术上的应用。

利用哈夫曼树,我们可以得到平均长度最短的编码。

这里我们以计算机操作码的优化问题为例来分析说明。

研究操作码的优化问题主要是为了缩短指令字的长度,减少程序的总长度以及增加指令所能表示的操作信息和地址信息。

要对操作码进行优化,就要知道每种操作指令在程序中的使用频率。

这一般是通过对大量已有的典型程序进行统计得到的。

设有7种不同的指令,其使用频率如下表所示:由于计算机内部只能识别0、1代码,所以若采用定长操作码,则需要3位(23=8)。

显然,有一条编码没有作用,这是一种浪费。

一段程序中若有n条指令,那么程序的总位数为3×n。

为了充分地利用编码信息和减少程序的总位数,我们可以采用变长编码。

如果对每一条指令指定一条编码,使得这些编码互不相同且最短,是否可以满足要求呢?即是否可以如下表所示这样编码呢?这样虽然可以使得程序的总位数达到最小,但机器却无法解码。

例如对编码串0010110该怎么识别呢?第一个0可以识别为I1,也可以和第二个0组成的串00一起被识别为I3,还可以将前三位识别为I6,这样一来,这个编码串就有多种译法。

因此,若要设计变长的编码,则这种编码必须满足这样一个条件:任意一个编码不能成为其它任意编码的前缀。

我们把满足这个条件的编码叫做前缀编码。

利用哈夫曼算法,可以使我们设计出最优的前缀编码。

首先,我们以每条指令的使用频率为权值构造哈夫曼树,如下图6.27所示:对于该二叉树,我们可以规定向左的分支标记为1,向右的分支标记为0。

这样,从根结点开始,沿线到达各频度指令对应的叶结点,所经过的分支代码序列就构成了相应频度指令的哈夫曼编码,如下图所示:可以验证,该编码是前缀编码。

若一段程序有1000条指令,其中I1大约有400条,I2大约有300条,I3大约有150,I4大约有50条,I5大约有40,I6大约有30,I7大约有30条。

对于定长编码,该段程序的总位数大约为3×1000=3000。

采用哈夫曼编码后,该段程序的总位数大约为1×400+2×300+3×150+5×(50+40+30+30)=2200。

可见,哈夫曼编码中虽然大部分编码的长度大于定长编码的长度3,却使得程序的总位数变小了。

可以算出该哈夫曼编码的平均码长为:3哈夫曼编码的实现过程3.1软件介绍MATLAB以矩阵作为基本编程单元,它提供了各种矩阵的运算与操作,并有较强的绘图功能。

MATLAB集科学计算、图像处理、声音处理于一身,是一个高度的集成系统,有良好的用户界面,并有良好的帮助功能。

MATLAB不仅流行于控制界,在机械工程、生物工程、语音处理、图像处理、信号分析、计算机技术等各行各业中都有极广泛的应用。

MATLAB语言的特点1.编程效率高2.用户使用方便3.扩充能力强4.语句简单,内涵丰富5.高效方便的矩阵和数组运算6.方便的绘图功能3.2设计内容已知一个信源的各符号概率,编写适当函数,对其进行哈夫曼编码,得出码字,平均码长和编码效率,总结此编码方法的特点和应用。

3.3设计步骤MATLAB的操作界面MATLAB操作界面主要分为:任务栏、命令窗、命令历史窗、当前目录浏览器、工作空间浏览器及一个“启动按钮”任务栏:位于软件的正上方。

各个菜单分别为:文件、编辑、视窗、调试、桌面、窗体、帮助这几个窗口,点击每个窗口可以选择需要的操作。

命令窗(Command Window):位于软件操作界面的右侧。

在此窗口里,可以输入各种指令、函数、变量表达式并进行各种操作。

该窗口用于输入命令并显示除图形以外的所有执行结果。

窗口中的“>>”为命令提示符,直接在其后面输入命令并按下回车键后,会出现计算结果在命令后面。

命令历史窗(Command History):位于软件操作界面的左下方。

这个窗口记录了命令窗口已经运行过的所有命令(指令、函数等),允许用户对这些命令进行选择、复制。

程序如下:(假定随机信源为3,1,3,2,4,3,2,1,2,3)clear all;I=[3,1,3,2,4,3,2,1,2,3];len=length(I);t=2;biaozhi=0;b(1)=I(1);for i=2:lenfor j=1:i-1if I(j)==I(i)biaozhi=1;break;endendif biaozhi==0b(t)=I(i);t=t+1;endbiaozhi=0;endfprintf('信源总长度:\n');disp(len); %信源总长度fprintf('字符:\n');disp(b );L=length(b);for i=1:Lfor j=1:lenif b(i)==I(j)a=a+1;count(i)=a;endendendcount=count/len;%各字符概率fprintf('各字符概率:\n');disp(count);p=count; %%%%%%%%%%%%%%%%%%%%%%%%%%% s=0;l=0;H=0;N=length(p);for i=1:NH=H+(- p(i)*log2(p(i)));%计算信源信息熵endfprintf('信源信息熵:\n');disp(H);tic;for i=1:N-1 %按概率分布大小对信源排序for j=i+1:Nif p(i)<p(j)m=p(j);p(j)=p(i);p(i)=m;endendQ=p;m=zeros(N-1,N);for i=1:N-1 %循环缩减对概率值排序,画出由每个信源符号概率到1.0 处的路径[Q,l]=sort(Q);m(i,:)=[l(1:N-i+1),zeros(1,i-1)];Q=[Q(1)+Q(2),Q(3:N),1];endfor i=1:N-1c(i,:)=blanks(N*N);endc(N-1,N)='0';c(N-1,2*N)='1';for i=2:N-1 %对字符数组c码字赋值过程,记下沿路径的“1”和“0”;c(N-i,1:N-1)=c(N-i+1,N*(find(m(N-i+1,:)==1))-(N-2):N*(find(m(N-i+1,:)==1)));c(N-i,N)='0';c(N-i,N+1:2*N-1)=c(N-i,1:N-1);c(N-i,2*N)='1';for j=1:i-1c(N-i,(j+1)*N+1:(j+2)*N)=c(N-i+1,N*(find(m(N-i+1,:)==j+1)-1)+1:N*find(m(N-i+1, :)==j+1));endendfor i=1:Nh(i,1:N)=c(1,N*(find(m(1,:)==i)-1)+1:find(m(1,:)==i)*N);%码字赋值ll(i)=length(find(abs(h(i,:))~=32)); %各码字码长endl=sum(p.*ll); %计算平均码长n=H/l; %计算编码效率fprintf('编码的码字:\n');disp(h) %按照输入顺序排列的码字fprintf('平均码长:\n');disp(l) %输出平均码长fprintf('编码效率:\n');disp(n) %输出编码效率4程序运行结果分析运行结果如下图所示:运行结果分析:从运行结果可知该结果与理论一致,并且可以看出哈夫曼编码的3个特点⑴哈夫曼码的编码方法保证了概率大的符号对应于短码,概率小的符号对应于长码。

相关文档
最新文档