哈夫曼树的建立及应用
- 格式:doc
- 大小:74.00 KB
- 文档页数:6
哈夫曼树的建立及应用C++作业+心得第一篇:哈夫曼树的建立及应用 C++ 作业+ 心得专业:计算机科学与技术班级:计算机09-1姓名: ***学号: 20指导老师:陈**评分:实验四哈夫曼树的建立及应用一、实验目的1、2、3、1、掌握哈夫曼树的基本概念及所有的存储结构。
掌握哈夫曼树的建立算法。
掌握哈夫曼树的应用(哈夫曼编码和译码)。
给定权值5,29,7,8,14,23,3,11,建立哈夫曼树,输出哈夫曼编码。
二、实习内容2、对上述给定的哈夫曼树及得到的哈夫曼编码,试输入一串二进制编码,输出它的哈夫曼译码。
三、算法描述将建立哈夫曼树、实现哈夫曼编码、哈夫曼译码都定义成子函数的形式,然后在主函数中调用它们。
建立哈夫曼树时,将哈夫曼树的结构定义为一个结构型的一维数组,每个元素含有四项:权值,双亲,左孩子,右孩子。
给定的权值可以从键盘输入,要输出所建立的哈夫曼树,只要输出表示哈夫曼树的一维数组中的全部元素即可。
要实现哈夫曼编码,只要在所建立的哈夫曼树上进行二进制编码:往左走,编码为0,往右走,编码为1,然后将从根结点到树叶中的所有0、1排列起来,则得到该树叶的哈夫曼编码。
哈夫曼编码可以用一个结构型的一维数组保存,每个元素包含:编码、编码的开始位置、编码所对应的字符三项。
程序清单:#include #include const int n=8;const int m=2*n-1;struct tree {float weight;int parent;int lch,rch;};struct codetype {int bits[n+1];int start;char ch;};tree hftree[m+1];struct codetype code[n+1];void creathuffmantree(){int i,j,p1,p2;float s1,s2;for(i=1;i<=m;i++){hftree[i].parent=0;hftree[i].lch=0;hftree[i].rch=0;hftree[i].weight=0;} cout<<“输入”<cin>>hftree[i].weight;for(i=n+1;i<=m;i++){p1=p2=0;s1=s2=32767;for(j=1;j<=i-1;j++)if(hftree[j].parent==0)if(hftree[j].weight{s2=s1;s1=hftree[j].weight;p2=p1;p1=j;}elseif(hftree[j].weight{s2=hftree[j].weight;p2=j;}hftree[p1].parent=i;hftree[p2].parent=i;hftree[i].lch=p1;hftree[i].rch=p2;hftree[i].weight=hftree[p1].weight+hftree[p2].weight;}} void huffcode(){codetype cd;int c,p;for(int i=1;i<=n;i++){cd.start=n+1;cd.ch=96+i;c=i;p=hftree[i].parent;while(p!=0){cd.start--;if(hftree[p].lch==c)cd.bits[cd.start]=0;else cd.bits[cd.start]=1;c=p;p=hftree[p].parent;}code[i]=cd;} for(i=1;i<=n;i++){cout<<“字符”<为:”<for(int j=code[i].start;j<=n;j++)cout<cout<>b;while((b=='0')||(b=='1')){if(b=='0')i=hftree[i].lch;else i=hftree[i].rch;if(hftree[i].lch==0){cout<i=m;}cin>>b;}} void main(){creathuffmantree();huffcode();trancode();} 运行结果:结果分析(心得体会):上网找了相关的内容才完成了这次实验,但总的来说,对数据结构的知识认识不深,通过这次的实验,我学会了哈夫曼树的建立及应用,我更懂得要编程序,就要学习更多的东西才行。
第三节哈夫曼树及其应用1.哈夫曼树的定义在二叉树中,一个结点到另一个结点之间的分支构成这两个结点之间的路径。
这三棵二叉树的带权路径长度分别为:WPL1=10*2+11*2+3*3+6*3+7*3+9*3=117WPL2=3*1+6*2+7*3+9*4+10*5+11*5=177WPL3=9*1+7*2+6*3+3*4+10*5+11*5=158构造哈夫曼树的过程:(1)将给定的n个权值{w1,w2,...,wn}作为n个根结点的权值构造一个具有n棵二叉树的森林{T1,T2,...,Tn},其中每棵二叉树只有一个根结点;(2)在森林中选取两棵根结点权值最小的二叉树作为左右子树构造一棵新二叉树,新二叉树的根结点权值为这两棵树根的权值之和;(3)在森林中,将上面选择的这两棵根权值最小的二叉树从森林中删除,并将刚刚新构造的二叉树加入到森林中;(4)重复上面(2)和(3),直到森林中只有一棵二叉树为止。
这棵二叉树就是哈夫曼树。
假设有一组权值{5,29,7,8,14,23,3,11},下面我们将利用这组权值演示构造哈夫曼树的过程。
这就是以上述8个权值为叶子结点权值构成的哈夫曼树,它的带权的路径长度为:WPL=(23+29)*2+(11+14)*3+(3+5+7+8)*4=2712.判定树在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设计直接影响着程序的执行效率。
例如,编制一个程序,将百分制转换成五个等级输出。
大家可能认为这个程序很简单,并且很快就可以用下列形式编写出来:if (socre<60) printf("bad");else if (socre<70) printf("pass");else if (score<80) printf("general");else if (score<90) printf("good");esle printf("very good");在实际应用中,往往各个分数段的分布并不是均匀的。
哈夫曼树的建立及操作哈夫曼树是一种用于数据压缩的树形数据结构,可以有效地压缩数据并减小存储空间。
本文将介绍哈夫曼树的建立方法和相关操作。
一、哈夫曼树的建立方法:1.首先,我们需要统计给定数据中每个字符出现的频率。
频率越高的字符将被赋予较短的编码,从而实现数据的压缩。
可以使用一个字典或哈希表来记录字符及其频率。
2.创建一个包含所有字符频率的节点列表。
每个节点包含一个字符及其对应的频率。
3.排序节点列表,按照频率从小到大的顺序进行排序。
4.创建一个空的二叉树,并将频率最低的两个节点作为子节点,合并为一个新的节点。
新节点的频率为两个子节点的频率之和。
将这个新节点插入到节点列表中。
5.从节点列表中移除原先的两个子节点,插入新节点。
保持列表的有序性。
6.重复步骤4和5,直到节点列表中只剩下一个节点。
7.最后剩下的节点即为哈夫曼树的根节点。
二、哈夫曼树的操作:1.获取哈夫曼编码:根据哈夫曼树的结构,可以通过遍历树的路径来获取每个字符的编码。
左子树表示0,右子树表示1、从根节点出发,依次遍历所有叶子节点,记录下每个字符对应的路径即可得到编码。
2.数据压缩:将原始数据中的每个字符替换为对应的哈夫曼编码,从而实现数据压缩。
根据频率,越常见的字符编码越短,可以大幅减小数据存储的空间。
3.数据解压:使用相同的哈夫曼树,将压缩后的二进制编码解码为原始字符,从而还原数据。
4. 哈夫曼树的存储和传输:为了实现数据的压缩和解压缩,哈夫曼树需要存储和传输。
可以使用二进制格式存储树的结构和频率信息,并在解压缩时重新构建树。
还可以考虑使用霍夫曼编码的变种,如Adaptive Huffman Coding(自适应哈夫曼编码),使得树结构可以随着数据的变化进行更高效的编码和解码。
总结:哈夫曼树是一种用于数据压缩的树形数据结构,可以通过统计字符频率来生成树,并生成对应的编码。
通过编码,可以实现原始数据的高效压缩和解压缩。
在实际应用中,哈夫曼树被广泛应用于数据压缩,如文件压缩、图像压缩等。
实验哈夫曼树的建立一、实验目的:1.理解哈夫曼树及其应用。
2.掌握生成哈夫曼树的算法。
二、实验内容:哈夫曼树,即最优树,是带权路径长度最短的树。
有着广泛的应用。
在解决某些判定问题上,及字符编码上,有着重要的价值。
构造一棵哈夫曼树,哈夫曼最早给出了算法,称为哈夫曼算法:(1)根据给定的N个权值W1,W2,W3,……,Wn ,构成N棵二叉树的集合F= T1,T2,T3,……,Tn ,其中每棵二叉树T1只有一个带权为WI的根结点,其左右子树均空。
(2)在F中选出两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的权值为其左右子树上的根结点的权值之和。
(3)在F中删除这两棵树,同时将新得到的加到F之中。
重复(2)和(3),直至F 中只剩一个为止。
三、程序流程图四、参考程序#include"stdio.h"#define LEN sizeof(struct HTnode)int i,l,n,w=0,c,start,a1,a2,f;struct HTnode {unsigned int weight;unsigned int parent,lchild,rchild;}*p,*HT;typedef char **Huffmancode;Huffmancode HC;char *cd;select(){int k=1,j,flag=0;while((HT+k)->parent!=0) k++;for(j=k+1;j<=n;j++,flag=0){if((HT+j)->parent!=0) flag=1;if((HT+j)->weight==0) flag=1;if(!flag) {if((HT+j)->weight<(HT+k)->weight) k=j;}}return(k);}main(){printf("\n赫夫曼树的建立:\n");printf("请输入权值(叶子)数目:");scanf("%d",&l);while(l<1) {printf("输入错误,请重新输入权值数目:"); scanf("%d",&l); }if(l==1) printf("\n只有一个权值,无须建立赫夫曼树!");else {n=2*l-1;HT=(struct HTnode*)malloc((n+1)*LEN);printf("请按对应顺序输入权值(输入一权值,键入一回车):\n");for(i=1,p=HT+1;i<=l;++i,++p){scanf("%d",&w);while(w<=0){printf("权值错,重新输入此权值:"); scanf("%d",&w);}p->weight=w; p->parent=0;p->lchild=0; p->rchild=0;}for(i=l+1;i<=n;++i,++p){p->weight=0; p->parent=0;p->lchild=0;}for(i=l+1;i<=n;++i){a1=select(); (HT+a1)->parent=i;a2=select(); (HT+a2)->parent=i;(HT+i)->lchild=a1;(HT+i)->rchild=a2;(HT+i)->weight=(HT+a1)->weight+(HT+a2)->weight;}HC=(Huffmancode)malloc((l+1)*sizeof(char *));cd=(char *)malloc(l*sizeof(char));*(cd+(l-1))='\0';for(i=1;i<=l;++i){start=l-1;for(c=i,f=(HT+i)->parent;f!=0;c=f,f=(HT+f)->parent)if((HT+f)->lchild==c) *(cd+(--start))='0';else *(cd+(--start))='1';*(HC+i)=(char *)malloc((l-start)*sizeof(char));strcpy(*(HC+i),(cd+start));}printf("\n对应的二进制赫夫曼编码为:\n");for(i=1;i<=l;++i){printf("%s",*(HC+i));printf(" ");}}}五、思考题目举一实例说明哈夫曼树的用途。
哈夫曼树的实际应用
哈夫曼树(Huffman Tree)是一种重要的数据结构,它在信息编码和压缩、数据传输和存储、图像处理等领域有广泛应用。
1. 数据压缩:哈夫曼树是一种无损压缩的方法,能够有效地减小数据的存储空间。
在进行数据压缩时,可以使用哈夫曼树构建字符编码表,将出现频率较高的字符用较短的编码表示,而出现频率较低的字符用较长的编码表示,从而减小数据的存储空间。
2. 文件压缩:在文件压缩领域,哈夫曼树被广泛应用于压缩算法中。
通过构建哈夫曼树,可以根据字符出现的频率来生成不同长度的编码,从而减小文件的大小。
常见的文件压缩格式如ZIP、GZIP等都使用了哈夫曼树。
3. 图像压缩:在图像处理中,哈夫曼树被用于图像压缩算法中。
通过将图像中的像素值映射为不同长度的编码,可以减小图像的存储空间,提高图像传输和存储的效率。
常见的图像压缩格式如JPEG、PNG等都使用了哈夫曼树。
4. 文件传输:在数据传输中,哈夫曼树被用于数据压缩和传输。
通过对数据进行压缩,可以减小数据的传输时间和带宽占用。
在传输过程中,接收方可以通过哈夫曼树解码接收到的数据。
5. 数据加密:在数据加密中,哈夫曼树可以用于生成密钥,从而实现数据的加密和解密。
通过将字符映射为不同长度的编码,可以实
现对数据的加密和解密操作。
哈夫曼树在信息编码和压缩、数据传输和存储、图像处理等领域有广泛应用,能够有效地减小数据的存储空间、提高数据传输效率、实现数据加密等功能。
数据结构课程设计_哈夫曼树哈夫曼树是数据结构课程设计中的一个重要内容,它是一种用于编码和压缩数据的树形结构。
在这篇文章中,我们将深入探讨哈夫曼树的原理、应用以及实现方法。
一、哈夫曼树的原理哈夫曼树是一种特殊的二叉树,它的构建依赖于哈夫曼编码的思想。
哈夫曼编码是一种变长编码方式,通过将频率较高的字符用较短的编码表示,而频率较低的字符用较长的编码表示,从而实现数据的高效压缩。
构建哈夫曼树的过程如下:1. 首先,将待编码的字符按照出现频率从小到大进行排序。
2. 然后,取出频率最小的两个字符,将它们作为叶子节点构建一个新的二叉树,该树的根节点的权值为这两个字符的频率之和。
3. 将新构建的二叉树插入到原有的字符列表中,并重新进行排序。
4. 重复步骤2和步骤3,直到只剩下一个根节点的二叉树为止,该树就是哈夫曼树。
二、哈夫曼树的应用哈夫曼树在数据压缩和编码中有着广泛的应用。
由于哈夫曼编码能够将频率较高的字符用较短的编码表示,从而减少了数据的存储空间,因此在文件压缩、图像压缩等领域被广泛应用。
在文件压缩中,哈夫曼树可以根据文件中字符的出现频率构建出一个最优的编码表,将文件中的字符替换为对应的哈夫曼编码,从而实现文件的高效压缩。
解压缩时,只需要根据哈夫曼编码表将编码还原为原始字符,即可恢复文件的原始内容。
在图像压缩中,哈夫曼树可以根据图像中像素值的出现频率构建出一个最优的编码表,将像素值替换为对应的哈夫曼编码,从而实现图像的高效压缩。
解压缩时,只需要根据哈夫曼编码表将编码还原为原始像素值,即可恢复图像的原始内容。
三、哈夫曼树的实现方法哈夫曼树的实现方法有多种,其中一种常见的方法是使用优先队列(也称为最小堆)来实现。
优先队列是一种特殊的队列,它的每个元素都有一个优先级,优先级高的元素先出队。
在构建哈夫曼树时,我们可以将字符和对应的频率作为优先队列中的元素,根据频率的大小来确定优先级。
每次从优先队列中取出两个频率最小的字符,将它们作为叶子节点构建一个新的二叉树,并将该二叉树的根节点插入到优先队列中。
赫夫曼树的作用及应用1.引言在计算机科学中,赫夫曼树是一种重要的数据结构,它被广泛应用于数据压缩、存储和解码等领域。
赫夫曼树以其高效的特点,成为了压缩算法中的重要组成部分。
本文将介绍赫夫曼树的作用以及它在不同应用领域中的具体应用。
2.赫夫曼树的基本概念赫夫曼树,也称为最优二叉树,是一种树形结构。
它的构建基于赫夫曼编码算法,该算法通过将频率较高的字符编码为较短的二进制码,从而实现数据的高效压缩。
3.赫夫曼树的构建赫夫曼树的构建过程包括以下几个步骤:1.统计字符频率:遍历待压缩的数据,统计各个字符出现的频率。
2.构建叶子节点:将每个字符及其频率作为叶子节点,构成初始的二叉树。
3.合并节点:选择两个频率最低的节点合并,并将合并后的节点作为新的节点插入二叉树中。
4.重复合并:重复执行合并节点的操作,直到只剩下一个节点,即赫夫曼树的根节点。
4.赫夫曼树的作用赫夫曼树在数据压缩和解压缩中发挥着重要作用,主要体现在以下几个方面:4.1数据压缩赫夫曼树通过赫夫曼编码将频率较高的字符编码为较短的二进制码,从而实现数据的高效压缩。
压缩后的数据体积大大减小,方便存储和传输。
4.2文件压缩赫夫曼树可用于对文件进行压缩,将文件中的字符编码为对应的二进制码,从而减小文件的大小。
在文件传输和存储中,减小文件的大小可以提高传输速度和节省存储空间。
4.3图像压缩赫夫曼树也可用于图像数据的压缩,通过对图像中的像素进行编码,减小图像的大小。
图像压缩在图像处理和存储中起到重要的作用,减小图像的大小可以提高图像的传输速度和存储效率。
4.4视频压缩赫夫曼树在视频编码中也有重要应用,通过对视频帧中的数据进行编码,实现对视频的压缩。
视频压缩可以降低视频的带宽占用率,提高视频传输的效率和稳定性。
5.赫夫曼树的应用举例除了数据压缩方面,赫夫曼树在其他领域也有广泛应用,以下列举几个常见的应用场景:5.1字符串匹配赫夫曼树可以用于字符串匹配算法中,通过构建赫夫曼树和相关数据结构,提高字符串匹配的效率和准确性。
哈夫曼树构建策略概述哈夫曼树是一种用于数据压缩和编码的树形数据结构。
通过使用不同频率的字符编码成不同长度的比特串,哈夫曼树可以实现高效的数据压缩和解压缩过程。
本文将概述哈夫曼树的构建策略,帮助读者了解其原理和应用。
一、哈夫曼树的基本概念哈夫曼树是一种特殊的二叉树,它的每个节点都代表一个字符以及其出现的频率。
频率越高的字符越靠近树的根部。
利用这种结构,我们可以给出每个字符的唯一编码。
二、哈夫曼树的构建步骤1. 统计字符频率:首先,需要统计需要进行压缩的文本中每个字符的出现频率。
这些频率将决定哈夫曼树的构建过程。
2. 构建初始森林:将每个字符和其对应的频率作为树的叶子节点,构建初始森林。
这些独立的树将作为哈夫曼树构建的基础。
3. 构建哈夫曼树:从初始森林中选取频率最低的两颗树,将它们合并成一颗新的树,并将合并后的树返回到初始森林中。
重复这个步骤,直到初始森林中只有一颗树为止。
这颗树就是哈夫曼树。
4. 生成编码表:通过遍历哈夫曼树,从根部到每个叶子节点,可以得到每个字符的编码。
一般来说,左分支表示编码为0,右分支表示编码为1。
三、哈夫曼树的应用哈夫曼树主要应用于数据压缩和编码。
通过将频率较高的字符编码为较短的比特串,我们可以实现对数据的高度压缩,从而减少存储空间和传输带宽的需求。
此外,哈夫曼树也可以用于优先队列的实现。
在优先队列中,每个元素的优先级由其出现频率或权重决定。
通过使用哈夫曼树,我们可以高效地插入、删除和获取具有最高优先级的元素。
四、总结哈夫曼树是一种用于数据压缩和编码的重要数据结构。
通过统计字符频率、构建初始森林和合并树节点的方式,我们可以构建出一颗高效的哈夫曼树,并生成每个字符的唯一编码。
利用哈夫曼树,我们可以实现对数据的高效压缩和解压缩操作。
同时,哈夫曼树还可以应用于优先队列等其他领域。
总之,了解和掌握哈夫曼树的构建策略对于理解数据压缩和编码领域的算法和技术至关重要。
通过深入研究哈夫曼树,我们可以进一步提高数据压缩和编码的效率,并在实际应用中取得更好的性能。
数据结构实验报告
专业:
班级:
姓名:
学号:
指导老师:
评分:
实验四哈夫曼树的建立及应用
一、实验目的
1、掌握哈夫曼树的基本概念及所有的存储结构。
2、掌握哈夫曼树的建立算法。
3、掌握哈夫曼树的应用(哈夫曼编码和译码)。
二、实习内容
1、给定权值5,29,7,8,14,23,3,11,建立哈夫
曼树,输出哈夫曼编码。
2、对上述给定的哈夫曼树及得到的哈夫曼编码,试输入一
串二
进制编码,输出它的哈夫曼译码。
三、算法描述
将建立哈夫曼树、实现哈夫曼编码、哈夫曼译码都定义成子函数的形式,然后在主函数中调用它们。
建立哈夫曼树时,将哈夫曼树的结构定义为一个结构型的一维数组,每个元素含有四项:权值,双亲,左孩子,右孩子。
给定的权值可以从键盘输入,要输出所建立的哈夫曼树,只要输出表示哈夫曼树的一维数组中的全部元素即可。
要实现哈夫曼编码,只要在所建立的哈夫曼树上进行二进制编码:往左走,编码为0,往右走,编码为1,然后将从根结点到树叶中的所有0、1排列起来,则得到该树叶的哈夫曼编码。
哈夫曼编码可以用一个结构型的一维数组保存,每个元素包含:编码、编码的开始位置、编码所对应的字符三项。
四、程序清单:
#include<iostream>
#include<string>
using namespace std;
int x1,x2,s,mm;
int ww[100];
struct element
{
int weight,lchild,rchild,parent;
string bianma;
};
element huffTree[100];
int huff[100];//存储100个权值的数组
void Select(element huffTree[],int m)
{
int min,min2,i;
min=min2=1000;
for(i=0;i<m;i++)
if(huffTree[i].parent==-1)
if(min>huffTree[i].weight )
{
min2=min;
min=huffTree[i].weight ;
x2=x1;
x1=i;
}
else if(min2>huffTree[i].weight )
{
min2=huffTree[i].weight ;
x2=i;
}
}
//哈夫曼树函数
void HuffmanTree(element huffTree[])
{
int i;
cout<<"请设置叶子节点的数量: ";
cin>>s;
cout<<"请依次输入这"<<s<<"个叶子节点的权值(以回车或者空格为结束输入一个叶子节点的权值): "<<endl;
for(i=0;i<s;i++)
cin>>huff[i];
for(i=0;i<2*s-1;i++)
{
huffTree[i].parent =-1;
huffTree[i].lchild =-1;
huffTree[i].rchild =-1;
}
for(int i1=0;i1<s;i1++)
huffTree[i1].weight=huff[i1];
for(int k=s;k<2*s-1;k++)
{
Select(huffTree,k);
huffTree[x1].parent =k;
huffTree[x2].parent =k;
huffTree[k].weight =huffTree[x1].weight +huffTree[x2].weight ;
huffTree[k].lchild =x1;
huffTree[k].rchild =x2;
}
}
void HuffmanBianMa(element huffTree[],int n)
{
int i,j=0;
for(i=2*(n-1);i>n-1;i--)
{
huffTree[huffTree[i].lchild ].bianma ="0";
huffTree[huffTree[i].rchild ].bianma ="1";
}
for(i=0,j=0;j<n;j++)
{
while(huffTree[i].parent !=-1)
{
huffTree[j].bianma
=huffTree[huffTree[i].parent].bianma +huffTree[j].bianma ;
i=huffTree[i].parent ;
}
i=j+1;
}
for(i=0;i<n;i++)
cout<<endl<<"叶子节点的权值为: "<<huffTree[i].weight <<" 的编码为: "<<huffTree[i].bianma <<" ";
}
void HuffmanJieMa(element huffTree[],int n)
{
cout<<endl<<"请输入解码串的长度: ";
cin>>mm;
cout<<"请输入依次输入解码串(以回车或者空格为结束输入一个字符): "<<endl;
for(int i1=0;i1<mm;i1++)
cin>>ww[i1];
int j=n,j1;
int i=0;
while(huffTree[j].lchild !=-1&&i<mm)
{
if(ww[i]==1) j=huffTree[j].rchild ;
else j=huffTree[j].lchild ;
i++;
if(huffTree[j].lchild ==-1)
{
cout<<huffTree[j].weight <<endl;
j1=j;
j=n;
}
else j1=j;
}
if(huffTree[j1].lchild !=-1) cout<<"部分信息丢失,输入错误,解码失败!"<<endl;
}
void main()
{
HuffmanTree(huffTree);
HuffmanBianMa(huffTree,s);
HuffmanJieMa(huffTree,2*(s-1));
system("pause");
}
解码成功:
解码失败:
心得体会:这次实验主要是让我们掌握哈夫曼树的建立算法和掌握哈夫曼树的应用。