霍夫曼树实验报告
霍夫曼树实验报告
![霍夫曼树实验报告](https://img.taocdn.com/s3/m/65423d9c0d22590102020740be1e650e52eacff3.png)
一、实验目的1. 理解霍夫曼树的基本概念和构造方法。
2. 掌握利用霍夫曼树进行数据压缩和编码的方法。
3. 提高数据结构在实际问题中的应用能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验原理霍夫曼树(Huffman Tree)是一种带权路径长度最短的二叉树,常用于数据压缩和编码。
在霍夫曼树中,每个叶子节点代表一个字符,其权值表示该字符在数据中出现频率。
构造霍夫曼树的过程如下:1. 将所有叶子节点作为一棵树的根节点。
2. 从树中选出两个权值最小的节点作为左右子节点,构成一棵新的二叉树。
3. 将新二叉树的根节点权值设为左右子节点权值之和。
4. 重复步骤2和3,直到只剩下一个根节点,即为霍夫曼树。
霍夫曼编码是一种根据字符出现频率进行编码的方法。
在霍夫曼编码中,权值较小的字符对应较短的编码,权值较大的字符对应较长的编码。
通过霍夫曼编码,可以有效地压缩数据,提高数据传输效率。
四、实验步骤1. 设计一个霍夫曼树构造函数,用于根据给定权值数组构造霍夫曼树。
2. 设计一个霍夫曼编码函数,用于根据霍夫曼树生成字符编码表。
3. 设计一个霍夫曼解码函数,用于根据编码表和解码字符串恢复原始数据。
4. 编写主函数,实现以下功能:a. 输入数据,包括字符和对应权值。
b. 构造霍夫曼树。
c. 生成霍夫曼编码表。
d. 对输入数据进行编码和解码。
e. 打印编码和解码结果。
五、实验结果与分析1. 实验数据假设有以下字符和对应权值:字符:A B C D E权值:15 4 3 2 42. 实验结果(1)霍夫曼树```23/ \15 8/ \ / \4 11 3 5/ \ / \A B C D E```(2)霍夫曼编码表字符:A B C D E编码:001 010 011 100 101(3)编码结果原始数据:ABCDAA编码结果:001010011010011001(4)解码结果编码结果:001010011010011001解码结果:ABCDAA3. 实验分析通过实验,我们可以发现霍夫曼树在数据压缩方面具有较好的效果。
霍夫曼编码设计实验报告
![霍夫曼编码设计实验报告](https://img.taocdn.com/s3/m/bdaa427c2e60ddccda38376baf1ffc4fff47e20b.png)
一、实验目的1. 理解霍夫曼编码的基本原理和算法流程。
2. 掌握霍夫曼编码的构建过程和编码方法。
3. 通过实验验证霍夫曼编码在数据压缩方面的效果。
4. 提高编程能力和数据结构应用能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验原理霍夫曼编码是一种基于字符出现频率进行编码的数据压缩方法。
其基本原理如下:1. 对字符进行统计,得到每个字符出现的频率。
2. 根据频率对字符进行排序,频率高的字符排在前面。
3. 构建霍夫曼树,将频率高的字符放在树的左侧,频率低的字符放在树的右侧。
4. 从树根到叶子节点,为每个字符分配一个二进制编码,频率高的字符用较短的编码表示,频率低的字符用较长的编码表示。
四、实验步骤1. 定义一个结构体HuffmanNode,用于存储字符及其频率。
2. 实现一个函数用于统计字符频率。
3. 实现一个函数用于构建霍夫曼树。
4. 实现一个函数用于生成霍夫曼编码。
5. 实现一个函数用于解码霍夫曼编码。
6. 编写主函数,进行实验验证。
五、实验过程1. 定义结构体HuffmanNode,用于存储字符及其频率。
```cppstruct HuffmanNode {char ch;int weight;HuffmanNode lchild, rchild;};```2. 实现一个函数用于统计字符频率。
```cppvoid StatFrequency(char str, int freq) {int length = strlen(str);for (int i = 0; i < 256; ++i) {freq[i] = 0;}for (int i = 0; i < length; ++i) {freq[(int)str[i]]++;}}```3. 实现一个函数用于构建霍夫曼树。
```cppHuffmanNode CreateHuffmanTree(int freq, int length) {HuffmanNode nodes = new HuffmanNode[length + 1];for (int i = 0; i < length; ++i) {nodes[i].ch = 'a' + i;nodes[i].weight = freq[i];nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = length; i < length + 1; ++i) {nodes[i].ch = '\0';nodes[i].weight = 0;nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = 0; i < length - 1; ++i) {HuffmanNode minNode1 = &nodes[0];HuffmanNode minNode2 = &nodes[1];for (int j = 0; j < length + 1; ++j) {if (nodes[j].weight < minNode1->weight) {minNode2 = minNode1;minNode1 = &nodes[j];} else if (nodes[j].weight < minNode2->weight && nodes[j].weight > minNode1->weight) {minNode2 = &nodes[j];}}nodes[i].weight = minNode1->weight + minNode2->weight;nodes[i].lchild = minNode1;nodes[i].rchild = minNode2;minNode1->parent = &nodes[i];minNode2->parent = &nodes[i];}return &nodes[length - 1];}```4. 实现一个函数用于生成霍夫曼编码。
数据结构实验实验报告Huffman赫夫曼编码及应用
![数据结构实验实验报告Huffman赫夫曼编码及应用](https://img.taocdn.com/s3/m/af193c62f61fb7360a4c6570.png)
实验报告课程名称:数据结构实验名称:赫夫曼编码及应用院(系):计算机与通信工程学院专业班级:计算机科学与技术姓名:学号:指导教师:2020 年 5 月12 日一、实验目的掌握赫夫曼树和赫夫曼编码的基本思想和算法的程序实现。
二、实验内容及要求1、任务描述a.提取原始文件中的数据(包括中文、英文或其他字符),根据数据出现的频率为权重,b.构建Huffman编码表;c.根据Huffman编码表对原始文件进行加密,得到加密文件并保存到硬盘上;d.将加密文件进行解密,得到解码文件并保存点硬盘上;e.比对原始文件和解码文件的一致性,得出是否一致的结论。
2、主要数据类型与变量a.对Huffman树采用双亲孩子表示法,便于在加密与解密时的操作。
typedef struct Huffman* HuffmanTree;struct Huffman{unsigned int weight; //权值unsigned int p, l, r;//双亲,左右孩子};b.对文本中出现的所有字符用链表进行存储。
typedef struct statistics* List;struct statistics {char str; //存储此字符int Frequency; //出现的频率(次数)string FinalNum; //Huffman编码struct statistics* Next;};3、算法或程序模块对读取到的文本进行逐字符遍历,统计每个字符出现的次数,并记录在创建的链表中。
借助Huffman树结构,生成结构数组,先存储在文本中出现的所有字符以及它们出现的频率(即权值),当作树的叶子节点。
再根据叶子节点生成它们的双亲节点,同样存入Huffman树中。
在完成对Huffman树的创建与存储之后,根据树节点的双亲节点域以及孩子节点域,生成每个字符的Huffman编码,并存入该字符所在链表节点的FinalNum域。
数据结构与算法实验报告_3霍夫曼树
![数据结构与算法实验报告_3霍夫曼树](https://img.taocdn.com/s3/m/412662305727a5e9856a617c.png)
实验四数据结构与程序设计专题实验报告赫夫曼树学院:物理与电子学院班级:电信1105班姓名:刘岩学号:1404110729实验报告一、实验任务实验题目:数据结构与程序设计专题实验二、实验内容实验三:树的基本操作及基于霍夫曼树的编码/译码(一)实验目的:掌握结构体、指针及二叉树的生成、遍历等操作掌握霍夫曼编码/译码的原理。
(二)基本要求:熟练掌握树的操作。
(三)内容提要:给定一段字符,构建霍夫曼树;根据该树求每个字符的编码,并对该段字符串进行编码;将得到的编码进行译码;基于该霍夫曼树,通过遍历算法来输出该树中的叶子节点。
注:在实现时要求霍夫曼树的左右孩子的大小关系(左孩子节点值小于右孩子节点),在遍历的时候也可以为递归与非递归办法寻找叶子节点。
三、要点分析题目中涉及的主要知识点:1、本程序参考霍夫曼算法(由给定的权值构造赫夫曼树):(1)由给定的n个权值{w0, w1, w2, …, w n-1},构造具有n棵二叉树的集合F = {T0, T1, T2, …, T n-1},其中每一棵二叉树T i只有一个带有权值w i的根结点,其左、右子树均为空。
(2)重复以下步骤, 直到F中仅剩下一棵树为止:① 在F中选取两棵根结点的权值最小的二叉树, 做为左、右子树构造一棵新的二叉树。
置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
② 在F中删去这两棵二叉树。
③ 把新的二叉树加入F。
2、用构造赫夫曼树以完成赫夫曼编码:把d1,d2,…, dn作为叶子结点,把w1,w2,…,wn作为叶子结点的权,构造赫夫曼树。
在赫夫曼树中结点的左分支赋0,右分支赋1,从根结点到叶子结点的路径上的数字拼接起来就是这个叶子结点字符的编码。
3、译码的过程是分解电文中的字符串,从根出发,按字符‘0’或‘1’确定找左孩子或右孩子,直至叶子节点,便求得该子串相应的字符。
四、程序的算法描述1、所用存储结构:typedef struct HfNode{int weight;int parent,lchild,rchild;}HfNode,*HuffmanTree; //动态分配数组存储霍夫曼树typedef char **HuffmanCode; //动态分配数组存储霍夫曼编码表2、程序中各函数的简要说明:(1)void Select(HuffmanTree &HT,int i,int &a,int &b)从前i个节点中选择权值最小的两个节点分别存入a,b中。
哈夫曼树_实验报告
![哈夫曼树_实验报告](https://img.taocdn.com/s3/m/bee43899ba4cf7ec4afe04a1b0717fd5370cb264.png)
一、实验目的1. 理解哈夫曼树的概念及其在数据结构中的应用。
2. 掌握哈夫曼树的构建方法。
3. 学习哈夫曼编码的原理及其在数据压缩中的应用。
4. 提高编程能力,实现哈夫曼树和哈夫曼编码的相关功能。
二、实验原理哈夫曼树(Huffman Tree)是一种带权路径长度最短的二叉树,又称为最优二叉树。
其构建方法如下:1. 将所有待编码的字符按照其出现的频率排序,频率低的排在前面。
2. 选择两个频率最低的字符,构造一棵新的二叉树,这两个字符分别作为左右子节点。
3. 计算新二叉树的频率,将新二叉树插入到排序后的字符列表中。
4. 重复步骤2和3,直到只剩下一个节点,这个节点即为哈夫曼树的根节点。
哈夫曼编码是一种基于哈夫曼树的编码方法,其原理如下:1. 从哈夫曼树的根节点开始,向左子树走表示0,向右子树走表示1。
2. 每个叶子节点对应一个字符,记录从根节点到叶子节点的路径,即为该字符的哈夫曼编码。
三、实验内容1. 实现哈夫曼树的构建。
2. 实现哈夫曼编码和译码功能。
3. 测试实验结果。
四、实验步骤1. 创建一个字符数组,包含待编码的字符。
2. 创建一个数组,用于存储每个字符的频率。
3. 对字符和频率进行排序。
4. 构建哈夫曼树,根据排序后的字符和频率,按照哈夫曼树的构建方法,将字符和频率插入到哈夫曼树中。
5. 实现哈夫曼编码功能,遍历哈夫曼树,记录从根节点到叶子节点的路径,即为每个字符的哈夫曼编码。
6. 实现哈夫曼译码功能,根据哈夫曼编码,从根节点开始,按照0和1的路径,找到对应的叶子节点,即为解码后的字符。
7. 测试实验结果,验证哈夫曼编码和译码的正确性。
五、实验结果与分析1. 构建哈夫曼树根据实验数据,构建的哈夫曼树如下:```A/ \B C/ \ / \D E F G```其中,A、B、C、D、E、F、G分别代表待编码的字符。
2. 哈夫曼编码根据哈夫曼树,得到以下字符的哈夫曼编码:- A: 00- B: 01- C: 10- D: 11- E: 100- F: 101- G: 1103. 哈夫曼译码根据哈夫曼编码,对以下编码进行译码:- 00101110111译码结果为:BACGACG4. 实验结果分析通过实验,验证了哈夫曼树和哈夫曼编码的正确性。
数据结构实验报告 huffman编码和解码算法
![数据结构实验报告 huffman编码和解码算法](https://img.taocdn.com/s3/m/eeb0408084868762caaed5d7.png)
(规格为A4纸或A3纸折叠)佛山科学技术学院(用四号宋体)实验报告(用小二号黑体)课程名称数据结构实验实验项目用Huffman树进行编码和解码算法专业班级姓名学号指导教师成绩日期(用小四号宋体)一、目的和要求1、通过本实验,熟悉二叉树、Huffman树的基本概念,掌握二叉树的存储结构及各种算法。
2、熟悉用Huffman树进行电文的加密与解密算法。
二、实验原理Huffman树是一种特殊的二叉树,其叶结点的编码是一种前缀码,同时,通过统计字符的频度,能够达到编码电文的最小化。
三、实验步骤1、统计电文中字符的出现频率。
2. 用统计频率建立Hffman树。
3.生成前缀码;4.建立huffman树的解码算法.5.用随机输入的电文完成编码与解码过程。
四、源程序#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 100struct HTNode{char a;int weight;int parent,lchild,rchild;}*HT; //动态分配数组存储赫夫曼树char **HC;int n=0,m=0;char *write()//存储输入的电文{char *p,*q;printf("请输入电文(结束输入请按enter):\n");p=(char *)malloc(MAX*sizeof(char));//申请存储输入的电文的空间if(!p) exit(0);q=p;scanf("%c",q);while(*q!='\n'){//******录入电文,每录入一个字符同时给电文长度计数器n加一*******//*****************遇到换行符时结束录入***************n=n+1;if(n>=MAX)//判断已申请的空间是否足够录入,不足则追加空间{p=(char *)realloc(q,(MAX+10)*sizeof(char));if(!p) exit(0);}q++;scanf("%c",q);}return(p);}void weight(char *p)//求电文中各字符的概率,并将该概率当作各字符的权值{char *q,*q1,temp;struct HTNode *q2;int i,j,t;q1=q=(char *)malloc(n*sizeof(char));for(;*p!='\n';p++,q1++) *q1=*p;//将电文存放到q1指向的空间中q1=q;for(i=0;i<n-1;i++){//*****对电文中的字符进行排序,使得相同的字符地址连续,方便统计***** t=i;for(j=i+1;j<n;j++)if(*(q1+t)>*(q1+j)) t=j;temp=*(q1+i);*(q1+i)=*(q1+t);*(q1+t)=temp;}temp=*q1;//标记当前为何种字符m=1;for(i=1;i<n;i++)//统计电文中出现过不同的字符的个数{q1++;if(temp!=*q1){m++;//字符种类计数器加一temp=*q1;}}q1=q;HT=(struct HTNode *)malloc(2*m*sizeof(struct HTNode));/*申请赫夫曼树HT的空间,其中0号单元不用*/q2=HT+1;//*****************初始化赫夫曼树HT*********************for(i=1;i<=n;){t=0;for(q2->a=*q1;*q1==q2->a;q1++){t++;i++;}q2->weight=(int)(t*100/n);q2->lchild=0;q2->parent=0;q2->rchild=0;q2++;}for(i=m+1;i<=2*m-1;i++,q2++){q2->lchild=0;q2->parent=0;q2->rchild=0;q2->weight=0;}free(q);}void Select(int t,int *s1,int *s2){/************在HT[1,t]选择parent为0且weight最小的两个结点,其序号分别为s1和s2。
(完整word版)哈夫曼树实验报告
![(完整word版)哈夫曼树实验报告](https://img.taocdn.com/s3/m/a395de289ec3d5bbfc0a747b.png)
实验报告1、实验目的:(1)理解哈夫曼树的含义和性质。
(2)掌握哈夫曼树的存储结构以及描述方法。
(3)掌握哈夫曼树的生成方法。
(4)掌握哈夫曼编码的一般方法,并理解其在数据通讯中的应用.2、实验内容:哈夫曼树与哈弗曼编码、译码a。
问题描述:哈夫曼问题的提出可以参考教材P。
145。
利用哈弗曼编码进行通信可以大大提高通信利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码.b。
算法提示:参见教材P.147—148算法6.12、6。
13的描述.3、实验要求:建立哈夫曼树,实现编码,译码。
错误!.初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
○2。
编码(Encoding).利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran 中的正文进行编码,然后将结果存入文件CodeFile中。
○3.译码(Decoding ).利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件T extFile 中。
错误!.输出代码文件(Print).将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
错误!。
输出哈夫曼树(TreePrinting).将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
测试数据:设权值c= (a,b, c, d , e, f,g,h)w=(5,29,7,8,14,23,3,11),n=8。
按照字符‘0’或‘1’确定找左孩子或右孩子,则权值对应的编码为:5:0001,29:11,7:1110,8:111114:110,23:01,3:0000,11:001。
赫夫曼树实验报告
![赫夫曼树实验报告](https://img.taocdn.com/s3/m/9597229b7e192279168884868762caaedd33ba9e.png)
赫夫曼树实验报告赫夫曼树实验报告引言:赫夫曼树是一种用于数据压缩的重要算法,它通过构建一棵二叉树来实现对数据的编码和解码。
本次实验旨在通过实际操作,深入了解赫夫曼树的原理和应用,并验证其在数据压缩中的有效性。
一、实验背景数据压缩在现代信息技术中起着至关重要的作用。
随着数据量的不断增加,如何有效地压缩数据成为了一个迫切的问题。
赫夫曼树作为一种经典的数据压缩算法,具有较高的压缩比和较快的解压速度,因此备受关注。
二、实验目的1. 了解赫夫曼树的原理和构建方法;2. 掌握赫夫曼编码的过程和步骤;3. 验证赫夫曼树在数据压缩中的有效性。
三、实验过程1. 构建赫夫曼树首先,我们需要统计待压缩数据中各个字符的出现频率。
然后,按照频率从小到大的顺序,将字符构建成一棵二叉树。
具体构建方法为:每次选取频率最低的两个字符,将它们作为左右子节点,生成一个新的节点,该节点的频率为左右子节点频率之和。
重复此过程,直到所有字符都被构建成树的节点。
2. 进行赫夫曼编码在赫夫曼树构建完成后,我们需要对每个字符进行编码。
编码的规则是:向左走为0,向右走为1。
从根节点开始,对每个字符进行路径搜索,直到找到对应的叶子节点,记录下路径上的0和1,即为该字符的编码。
3. 数据压缩与解压缩利用赫夫曼编码,我们可以对待压缩数据进行压缩。
将每个字符替换为对应的编码后,将所有编码拼接起来,即可得到压缩后的数据。
解压缩则是将编码根据赫夫曼树进行反向解码,得到原始数据。
四、实验结果通过实验,我们将不同类型的数据进行了压缩和解压缩,并与原始数据进行了对比。
结果表明,赫夫曼树在数据压缩中表现出色,能够显著减小数据的大小,同时保持数据的完整性。
五、实验总结赫夫曼树作为一种高效的数据压缩算法,具有广泛的应用前景。
通过本次实验,我们深入了解了赫夫曼树的原理和构建方法,并验证了其在数据压缩中的有效性。
赫夫曼树的应用不仅可以提高数据传输的效率,还可以节省存储空间,对于大数据时代的到来具有重要意义。
huffman实验报告
![huffman实验报告](https://img.taocdn.com/s3/m/2f2cc749f7ec4afe04a1dfeb.png)
一、问题描述1. 实验题目:huffman编解码2. 基本要求:初始化(I nitialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman 树,并将它存入hfmTree 中。
编码(E ncoding)。
利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree 中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
解码(D ecoding)。
利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
打印代码文件(Print)。
将文件CodeFile以紧凑的格式显示在终端上,每行 50 个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
打印Huffman树(T ree Printing)。
将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。
3. 测试数据:用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编字符集大小 n,n个字符和 n个权值均从终端读入,初始化后的huffman树存储在hfmTree文件中,待编码文件为ToBeTran,编码结果以文本的方式存储在文件CodeFile中,解码文件存在TextFile中,打印的编码和赫夫曼树分别存储在CodePrint和TreePrint文件中。
用户界面可以设计为“菜单”方式:显示上述功能符号,再加上一个退出功能“Q”,表示退出(quit)。
用户键入一个选择功能符,此功能执行完毕后再显示此菜单,直至某次用户选择了Q为止。
二、需求分析1. 本程序可以根据输入字符集和频度建立huffman树并且对给定文本进行编解码,还可以直接读入建立好的huffman树再对给定文本编解码,打印编码、解码结果、表格形式及树形的huffman树。
霍夫曼编码的实验报告(3篇)
![霍夫曼编码的实验报告(3篇)](https://img.taocdn.com/s3/m/f37bbf09571252d380eb6294dd88d0d233d43ca4.png)
第1篇一、实验目的1. 理解霍夫曼编码的基本原理和实现方法。
2. 掌握霍夫曼编码在数据压缩中的应用。
3. 通过实验,加深对数据压缩技术的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 20194. 数据源:文本文件三、实验原理霍夫曼编码是一种常用的数据压缩算法,适用于无损数据压缩。
它通过使用变长编码表对数据进行编码,频率高的数据项使用短编码,频率低的数据项使用长编码。
霍夫曼编码的核心是构建一棵霍夫曼树,该树是一种最优二叉树,用于表示编码规则。
霍夫曼编码的步骤如下:1. 统计数据源中每个字符的出现频率。
2. 根据字符频率构建一棵最优二叉树,频率高的字符位于树的上层,频率低的字符位于树下层。
3. 根据最优二叉树生成编码规则,频率高的字符分配较短的编码,频率低的字符分配较长的编码。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 在解码过程中,根据编码规则恢复原始数据。
四、实验步骤1. 读取文本文件,统计每个字符的出现频率。
2. 根据字符频率构建最优二叉树。
3. 根据最优二叉树生成编码规则。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 将压缩后的数据写入文件。
6. 读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
7. 比较原始数据和恢复后的数据,验证压缩和解码的正确性。
五、实验结果与分析1. 实验数据实验中,我们使用了一个包含10000个字符的文本文件作为数据源。
在统计字符频率时,我们发现字符“e”的出现频率最高,为2621次,而字符“z”的出现频率最低,为4次。
2. 实验结果根据实验数据,我们构建了最优二叉树,并生成了编码规则。
使用编码规则对数据源进行编码,压缩后的数据长度为7800个字符。
将压缩后的数据写入文件,文件大小为78KB。
接下来,我们读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
比较原始数据和恢复后的数据,发现两者完全一致,验证了压缩和解码的正确性。
数据结构实验报告(哈夫曼树)
![数据结构实验报告(哈夫曼树)](https://img.taocdn.com/s3/m/3654733b69dc5022abea003c.png)
数据结构实验报告实验题目:Huffman编码与解码姓名:学号:院系:实验名称:Huffman编码与解码实验问题描述:本实验需要以菜单形式完成以下功能:1.输入电文串2.统计电文串中各个字符及其出现的次数3.构造哈弗曼树4.进行哈弗曼编码5.将电文翻译成比特流并打印出来6.将比特流还原成电文数据结构的描述:逻辑结构:本实验可用二叉树实现,其逻辑结构为一对二的形式,即一个结点对应两个结点。
在实验过程中我们也应用到了栈的概念。
存储结构:使用结构体来对数据进行存储:typedef struct{int weight;int parent,lc,rc;}HTNode,*HuffmanTree;typedef struct LNode{char *elem;int stacksize;int top;}SqStack;在main函数里面定义一个哈弗曼树并实现上述各种功能。
程序结构的描述:本次实验一共构造了10个函数:1.void HuffTree(HuffmanTree &HT,int n[],int mun);此函数根据给定的mun个权值构建哈弗曼树,n[]用于存放num个权值。
2.void Select(HuffmanTree &HT,int n,int i,int &s1,int &s2);此函数用于在HT[1,i-1]中选择parent为0且weight为最小的两个结点,其下标分别为s1,s2.3.void HuffmanCoding(HuffmanTree HT,char **&HC,int n);此函数从哈弗曼树HT上求得n 个叶子结点的哈弗曼编码并存入数组HC中。
4.void Coding(HuffmanTree HT,char **HC,int root,SqStack &S);此函数用于哈弗曼编码,先序遍历哈弗曼树HT,求得每个叶子结点的编码字符串,存入数组HC,S为一个顺序栈,用来记录遍历路径,root是哈弗曼数组HT中根结点的位置下标。
哈夫曼编码实验报告
![哈夫曼编码实验报告](https://img.taocdn.com/s3/m/371ab2c7f46527d3250ce0ac.png)
哈夫曼编码实验报告霍夫曼(Huffman)编码属于码词长度可变的编码类,是霍夫曼在1952年提出的一种编码方法,即从下到上的编码方法。
同其他码词长度可变的编码一样,可区别的不同码词的生成是基于不同符号出现的不同概率。
生成霍夫曼编码算法基于一种称为“编码树”(coding tree)的技术。
算法步骤如下:(1)初始化,根据符号概率的大小按由大到小顺序对符号进行排序。
(2)把概率最小的两个符号组成一个新符号(节点),即新符号的概率等于这两个符号概率之和。
(3)重复第2步,直到形成一个符号为止(树),其概率最后等于1。
(4)从编码树的根开始回溯到原始的符号,并将每一下分枝赋值为1,上分枝赋值为0。
以下这个简单例子说明了这一过程。
1).字母A,B,C,D,E已被编码,相应的出现概率如下:p(A)=0.16, p(B)=0.51, p(C)=0.09, p(D)=0.13, p(E)=0.11 2).C和E概率最小,被排在第一棵二叉树中作为树叶。
它们的根节点CE的组合概率为0.20。
从CE到C的一边被标记为1,从CE到E的一边被标记为0。
这种标记是强制性的。
所以,不同的哈夫曼编码可能由相同的数据产生。
3).各节点相应的概率如下:p(A)=0.16, p(B)=0.51, p(CE)=0.20, p(D)=0.13D和A两个节点的概率最小。
这两个节点作为叶子组合成一棵新的二叉树。
根节点AD的组合概率为0.29。
由AD到A的一边标记为1,由AD到D的一边标记为0。
如果不同的二叉树的根节点有相同的概率,那么具有从根到节点最短的最大路径的二叉树应先生成。
这样能保持编码的长度基本稳定。
4).剩下节点的概率如下:p(AD)=0.29, p(B)=0.51, p(CE)=0.20AD和CE两节点的概率最小。
它们生成一棵二叉树。
其根节点ADCE 的组合概率为0.49。
由ADCE到AD一边标记为0,由ADCE到CE 的一边标记为1。
赫夫曼树的实验报告
![赫夫曼树的实验报告](https://img.taocdn.com/s3/m/1a558f702bf90242a8956bec0975f46527d3a7e8.png)
一、实验目的1. 理解赫夫曼树的概念和原理;2. 掌握赫夫曼树的构建方法;3. 学会使用赫夫曼树进行数据压缩和解压缩;4. 了解赫夫曼树在实际应用中的优势。
二、实验原理赫夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树。
在构建赫夫曼树的过程中,每次选择两个权值最小的节点作为左右子节点,然后合并成一个新的节点,权值为两个子节点权值之和。
重复此过程,直到只剩下一个节点,即为赫夫曼树的根节点。
赫夫曼树在数据压缩中的应用主要体现在编码和解码过程中。
通过对字符进行赫夫曼编码,可以将字符序列转换成二进制序列,从而减少数据存储空间。
在解码过程中,根据赫夫曼树的结构,可以将二进制序列还原成原始字符序列。
三、实验内容1. 构建赫夫曼树(1)输入字符及其权值,例如:A=5, B=9, C=12, D=13, E=16, F=45。
(2)将输入的字符和权值放入最小堆中,每次取出两个最小权值的节点,合并成一个新的节点,权值为两个子节点权值之和。
(3)重复步骤(2),直到只剩下一个节点,即为赫夫曼树的根节点。
2. 使用赫夫曼树进行数据压缩和解压缩(1)根据赫夫曼树生成字符的编码,例如:A=01, B=100, C=101, D=110, E=1110, F=1111。
(2)对输入的字符序列进行编码,例如:输入字符串"ABCDEF",编码后为"01010010101111111111"。
(3)将编码后的二进制序列存储或传输。
(4)接收方根据赫夫曼树的结构,对二进制序列进行解码,还原成原始字符序列。
四、实验结果与分析1. 实验结果(1)构建赫夫曼树```F/ \B D/ \ / \A C E G```(2)字符编码```A=01, B=100, C=101, D=110, E=1110, F=1111```(3)输入字符串"ABCDEF"的编码结果为"01010010101111111111"。
(精选)哈夫曼树及其操作-数据结构实验报告
![(精选)哈夫曼树及其操作-数据结构实验报告](https://img.taocdn.com/s3/m/2c4fc274a5e9856a561260c6.png)
电子科技大学实验报告课程名称:数据结构与算法学生姓名:陈*浩学号:************* 点名序号: *** 指导教师:钱** 实验地点:基础实验大楼实验时间: 2015.5.72014-2015-2学期信息与软件工程学院实验报告(二)学生姓名:陈**浩学号:*************指导教师:钱**实验地点:科研教学楼A508实验时间:2015.5.7一、实验室名称:软件实验室二、实验项目名称:数据结构与算法—树三、实验学时:4四、实验原理:霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。
1952年,David A. Huffman在麻省理工攻读博士时所发明的。
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
例如,在英文中,e的出现机率最高,而z的出现概率则最低。
当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。
二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
霍夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。
所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。
树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。
实验四__huffman树的实现
![实验四__huffman树的实现](https://img.taocdn.com/s3/m/c3425bde84254b35eefd345e.png)
实验四 huffman树的实现(2学时)
一、实验目的
1、掌握Huffman树的构造方法。
2、掌握Huffman编码的构造方法。
二、实现内容
[基本要求]用顺序存储结构实现存储
[实现提示]顺序存储结构是随机存储结构,直接数组来存储相关数据,用下标来表示栈顶,数据存储从下标0开始存储数据。
循环队列的处理可以用指针回绕的方式来实现,
[程序实现]
课程结束后的代码
三、实验要求
给定权值分别为5,29,7,8,14,23,3,11的集合,利用静态链表存储哈夫曼树,先构造哈夫曼树,再构造该哈夫曼树的哈夫曼编码。
四、实验报告要求
1、给出程序原代码;
2、给出程序测试数据;
3、编程、调试过程中主要难点及解决方法记录。
4、思考以下问题:
如何进行译码操作呢?。
Huffman树实验报告
![Huffman树实验报告](https://img.taocdn.com/s3/m/8c61c8ca89eb172ded63b75d.png)
Huffman编码及译码实验报告姜流PB12210218问题的描述:对传输的电文统计出现的字符及次数并进行Huffman编码,生成Huffman树,编码形式为1,0两种数字,打印出比特流,再将比特流译码成字符。
问题的输入输出:1.用户从键盘输入任意长度的任意字符,打印出出现的不同字符及次数;2.根据不同字符的权重生成Huffmam树并先序打印出来;3.根据Huffman树进行编码,打印出来比特流;4.将比特流转换成电文字符打印出来;算法的描述:1.统计字符功能的算法:用p指向输入的字符串,另开两个数组,一个是ch[],用来存放不同的字符,另一个是k[]用来存放各个不同字符的次数,对输入的字符串逐个字符依次比较,就可以完成字符统计功能。
2.生成Huffamn树算法:采用经典的生成算法,每次找两个权重最小的节点合并成一个节点,一直到最后没有节点,本次实验采用左孩子权重小于右孩子的规则进行生成。
3.Huffman编码算法:先序遍历生成的Huffman树,每次向左拐就将1压栈,向右拐就将0压栈,直到访问到叶子,将栈里的1,0字符copy到相应字符的编码,就然后进行出栈操作,直到访问完全部的节点。
4.Hufman译码算法:对输入的比特流进行逐个访问,若为1,在Huffman树上左拐,若为0,在Huffman树上右拐,一直到叶子,则叶子上的字符就是比特流对应的字符,然后再从根节点开始译码,直到比特流结束,即可译出所有的电文打印。
数据结构的描述:1.存放编码的栈:typedef struct{ char *base;char *top;int stacksize;}SqStack;2.Huffman树的节点:typedef struct{int weight,parent,lchild,rchild;}HTNode;3.Huffman树结构体:typedef struct{HTNode *Htree;int root;}HuffmanTree;5.双指针类型:存放每个字符对应编码#define HuffmanCode char **HuffmanCode HC=NULL;//初始时为空程序结构的描述:Status EmptyStack(SqStack s);Status Increment(SqStack &s);void InitStack(SqStack &s);void push(SqStack &s,char e);void pop(SqStack &s,char &e);Status Getop(SqStack &s,char &e);int StackLength(SqStack S);//以上关于栈的通用函数void select(HTNode *HT,int k,int &s);void CreateHuffman(HuffmanTree &T,int *w,int n);void Coding(HuffmanTree T,int i,SqStack &S,char **HC);void HuffmanCoding(HuffmanTree T,HuffmanCode &HC,int n);void Decoding(HuffmanTree T,char *s);void Print(HuffmanTree T);int compare(char ch[],char cha,int &n);void stat(char *s,char ch[],int k[],int &count);//完成各功能的函数main{ //主函数中对各个子函数调用顺序stat(s,ch,k,count);//以上为字符统计功能CreateHuffman(T,w,n);Print(T);//以上为构造HuffmanTree,并打印HuffmanCoding(T,HC,n);//以上为将每个字符翻译成比特文p=s;//puts(s);while(*p){i=compare(ch,*p,n);//printf("%d\n",n);printf("%s",HC[n+1]);p++;}printf("\n");//以上为将电文翻译为比特文printf("input the bits\n");gets(s1);Decoding(T,s1);//译码}调试分析:1.字符统计功能:结果是对的2.生成Huffman树并打印:结果是与输入相符合的3.将各个字符编码,成为比特流:结果很正确4.将比特流译码成为电文:结果输入的字符时相同的调试中遇到的问题:在创建Huffman树时,一开始是用scanf,但是调试的时候却总是不正确,查阅scanf函数原型后发现scanf在读字符时把空格也认为是有效字符,因此空格不能作为间隔符,建议用getchar(),gets()等函数。
最新赫夫曼树实验报告
![最新赫夫曼树实验报告](https://img.taocdn.com/s3/m/b617950f102de2bd97058803.png)
最新赫夫曼树实验报告实验原理:霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的爛编码(权编码)算法。
1952年,David A. Huffman在麻省理工攻读博士时所发明的。
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
例如,在英文中,e的出现机率最高,而z的出现概率则最低。
当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。
二者相比,e使用了一般编码的1/8的长度, z则使用了3倍多。
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
霍夫曼树乂称最优二义树,是一种带权路径长度最短的二叉树。
所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度 (若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。
树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(Wl*Ll+W2*L2+W3*L3+...+Wn*Ln), N 个权值Wi (i=l,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li (i=l,2,...n)o 可以证明霍夫曼树的WPL是最小的。
实验目的:本实验通过编程实现赫夫曼编码算法,使学生掌握赫夫曼树的构造方法, 理解树这种数据结构的应用价值,并能熟练运用C语言的指针实现构建赫夫曼二义树,培养理论联系实际和自主学习的能力,加强对数据结构的原理理解,提高编程水平。
实验内容:(1)实现输入的英文字符串输入,并设计算法分别统计不同字符在该字符串中出现的次数,字符要区分大小写;(2)实现赫夫曼树的构建算法;(3)遍历赫夫曼生成每个字符的二进制编码;(4)显示输出每个字母的编码。
霍夫曼算法实验报告
![霍夫曼算法实验报告](https://img.taocdn.com/s3/m/ed4f2342b6360b4c2e3f5727a5e9856a57122649.png)
一、实验目的1. 理解霍夫曼算法的基本原理和过程。
2. 掌握霍夫曼算法的编程实现。
3. 分析霍夫曼算法的复杂度和性能。
二、实验原理霍夫曼算法是一种贪心算法,用于数据压缩。
其基本思想是根据字符出现的频率,构造出一棵最优二叉树,从而得到最优的编码方案。
霍夫曼算法的步骤如下:1. 统计每个字符的出现频率。
2. 将频率相同的字符视为一类,按照频率从小到大排序。
3. 将排序后的字符中频率最小的两个字符合并成一个新字符,新字符的频率为两个字符频率之和。
4. 将新字符插入到排序后的字符中,并重新排序。
5. 重复步骤3和4,直到只剩下一个字符为止。
6. 根据合并的顺序,从根节点到叶子节点的路径上,将0和1分别赋给路径,形成每个字符的霍夫曼编码。
三、实验内容1. 编写程序实现霍夫曼算法。
2. 对给定的字符集进行编码和解码。
3. 分析霍夫曼算法的复杂度和性能。
四、实验步骤1. 编写程序,统计字符集的频率。
2. 根据频率构造最优二叉树。
3. 根据最优二叉树生成霍夫曼编码。
4. 编写解码程序,根据霍夫曼编码解码字符。
5. 测试程序,分析霍夫曼算法的复杂度和性能。
五、实验结果与分析1. 实验结果(1)霍夫曼编码示例假设字符集为:{a, b, c, d, e, f},频率分别为:{4, 2, 3, 5, 7, 8}。
(2)霍夫曼编码根据霍夫曼算法,得到以下编码:a: 0b: 10c: 110d: 1110e: 1111f: 100(3)解码根据霍夫曼编码,解码结果为:{a, b, c, d, e, f}。
2. 实验分析(1)复杂度分析霍夫曼算法的时间复杂度为O(nlogn),其中n为字符集的长度。
这是因为算法需要构建一个最优二叉树,而构建最优二叉树的时间复杂度为O(nlogn)。
(2)性能分析霍夫曼编码具有较好的压缩效果,其平均编码长度较其他编码方法短。
当字符集中字符的频率差异较大时,霍夫曼编码的压缩效果更明显。
六、实验总结通过本次实验,我们掌握了霍夫曼算法的基本原理和编程实现,分析了算法的复杂度和性能。
哈夫曼树实验报告
![哈夫曼树实验报告](https://img.taocdn.com/s3/m/33c62a02814d2b160b4e767f5acfa1c7ab00821d.png)
一、实验目的1. 理解哈夫曼树的基本概念和构造方法。
2. 掌握哈夫曼编码的原理和实现过程。
3. 通过实验加深对数据结构中树型结构应用的理解。
二、实验原理哈夫曼树(Huffman Tree)是一种带权重的二叉树,用于实现哈夫曼编码。
其基本思想是:将字符按照在数据集中出现的频率进行排序,然后选取两个最小频率的字符合并成一个新节点,其频率为两个字符频率之和,重复此过程,直到只剩下一个节点,即为哈夫曼树的根节点。
哈夫曼编码是一种基于哈夫曼树的编码方法,其原理是将每个字符映射到一个唯一的二进制序列,序列的长度与字符在数据集中出现的频率成反比。
频率越高,编码的长度越短,从而提高信息传输的效率。
三、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019四、实验步骤1. 初始化(1)从数据文件中读取字符及其频率。
(2)构建一个优先队列(最小堆),将字符和频率存储在队列中。
2. 构建哈夫曼树(1)从优先队列中取出两个频率最小的节点,合并成一个新节点,其频率为两个节点频率之和。
(2)将新节点插入优先队列中。
(3)重复步骤(1)和(2),直到优先队列中只剩下一个节点,即为哈夫曼树的根节点。
3. 哈夫曼编码(1)遍历哈夫曼树,从根节点到叶子节点的路径上,左子树表示0,右子树表示1。
(2)将每个叶子节点的字符和对应的编码存储在哈夫曼编码表中。
4. 编码(1)读取待编码的文本。
(2)根据哈夫曼编码表,将文本中的每个字符映射到对应的编码。
(3)将编码序列写入文件。
5. 译码(1)读取编码文件。
(2)从哈夫曼树的根节点开始,根据编码序列的每一位,判断是左子树还是右子树。
(3)当到达叶子节点时,输出对应的字符。
(4)重复步骤(2)和(3),直到编码序列结束。
五、实验结果与分析1. 实验结果(1)成功构建了哈夫曼树,并生成了哈夫曼编码表。
(2)对给定的文本进行了编码和译码,验证了编码的正确性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二二叉树的遍历及霍夫曼编码班级:计科1101班学号:0909101605姓名:杜茂鹏2013年5月22日一、实验目的掌握二叉树的建立及遍历操作,霍夫曼编码基本操作及存储结构表示二、实验内容1. 系统要求包含以下功能1)初始化:从终端读入字符集大小n,以及n个字符和n个权值(或者读入字符集和频度数据文件),建立哈夫曼树,并将哈夫曼树存入到文件HfmTree 中。
2)编码:利用已建好的哈夫曼树(如果不在内存中,则从文件中读入),从文件ToBeTran中读入原文,对原文进行编码,将编码后的结果存入文件CodeFile 中。
3)译码:利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
4)打印:打印输出哈夫曼树,显示ToBeTran, TextFile和CodeFile文件的内容。
三、实验要求1.在上机前写出全部源程序;2.能在机器上正确运行程序;3.用户界面友好。
四、概要设计1)首先动态分配数组存储霍夫曼树及存储霍夫曼编码表,然后从终端或文件读入霍夫曼树的字符变量及其频度,初始化建立霍夫曼树并将其写入文件HfmTree.txt中。
2)从指定的文件succe.txt中读入原文,利用已经编好的霍夫曼树对其编码,将编码结果写入文件Coding.txt保存。
3)利用已建好的哈夫曼树将文件Coding.txt中的代码进行译码,结果存入文件decoding.txt中。
五、测试数据:2.原文内容“THIS IS MY PROGRAM”六、详细设计实验内容(原理、操作步骤、程序代码)//建立霍夫曼树,对原文进行编码、译码#include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<string.h>typedef struct tree{char ch;int weight;//权值int parent,lchild,rchild;}HTNode,*HuffmanTree;//动态分配数组存储霍夫曼树typedef char **HuffmanCode;//动态分配数组存储霍夫曼编码表void Select(HuffmanTree &HT,int* s1,int* s2,int n){int j;int min1=10000;for(j=1;j<=n;j++){if(HT[j].parent==0&&min1>HT[j].weight){min1=HT[j].weight;*s1=j;}}int min2=10000;for(j=1;j<=n;j++){if(HT[j].parent==0&&min2>HT[j].weight&&j!=*s1){min2=HT[j].weight;*s2=j;}}}void HuffmanBiTree(HuffmanTree &HT,char *c,int *w,int n)//w存放n个字符的权值(>0),构造霍夫曼树HT,并求出n个字符的霍夫曼编码HC{int i;if(n<=1)return;int m=2*n-1;//霍夫曼树的结点数HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用for(i=1;i<=n;++i){HT[i].ch=c[i-1];HT[i].weight=w[i-1];HT[i].lchild=0;HT[i].parent=0;HT[i].rchild=0;}for(;i<=m;++i){HT[i].ch=NULL;HT[i].weight=0;HT[i].lchild=0;HT[i].parent=0;HT[i].rchild=0;}for(i=n+1;i<=m;i++)//建霍夫曼树{int s1,s2;Select(HT,&s1,&s2,i-1);//在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2HT[s1].parent=i;HT[s2].parent=i;HT[i].lchild=s1;HT[i].rchild=s2;HT[i].weight=HT[s1].weight+HT[s2].weight;}FILE *IN;if((IN=fopen("Hfmtree.txt","w+"))==NULL){printf("file open error!");exit(1);}for(int i=1;i<=2*n-1;i++){fprintf(IN,"%c,%d,%d,%d,%d",HT[i].ch,HT[i].weight,HT[i].parent,HT[i].lchild, HT[i].rchild);//将结构体数组HT对应的值按照%c%d..格式输入到文件中fputs("\n",IN); //在文件中输入换行符}fclose(IN);}//从叶子到根逆向求每个字符的霍夫曼编码void HuffmanBicode(HuffmanCode &HC,int n,HuffmanTree &HT){HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针向量char *cd=(char *)malloc(n*sizeof(char)); //分配求编码的工作空间cd[n-1]='\0'; //编码结束符int i;for(i=1;i<=n;++i) //逐个字符求霍夫曼编码{int start=n-1; //编码结束位置for(int c=i,f=HT[i].parent;f!=0;c=f,f=HT[c].parent)//从叶子到根逆向求编码if(HT[f].lchild==c)cd[--start]='0';elsecd[--start]='1';HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间strcpy(HC[i],&cd[start]); //复制}free(cd);}void CodingFile(HuffmanTree &HT,HuffmanCode &HC,int n){char ch;int i;FILE *IN,*OUT; //两个文件指针,分别指向打开文件和生成文件if ((IN = fopen("success.txt", "r")) == NULL){printf("File Open Error!\n");exit(1);}if ((OUT = fopen("coding.txt", "w+")) == NULL){printf("File Open Error!\n");exit(1);}while (!feof(IN)) //如果文件结束,feof返回1,否则返回0{ch = fgetc(IN); //依次得到文件中的字符i = 1;while ((HT[i].ch != ch) && (i <= n)){i++;if (i > n)return;}/* 将ch代表的字符的编码写入到输出文件*/fputs(HC[i], OUT);}fclose(IN); //关闭文件fclose(OUT);}void Decoding(HuffmanTree &HT,int n) //译码函数{char sh;FILE *P1,*P2,*P3;if((P1=fopen("coding.txt","r"))==NULL){printf("File open error");exit(1);}if((P2=fopen("decoding.txt","w+"))==NULL){printf("File open error");exit(1);}int f=2*n-1;while (!feof(P1)){sh=fgetc(P1);printf("%c",sh);if(sh=='1') //读到字符为1时,在霍夫曼树中表示为它的右孩子f=HT[f].rchild;if(sh=='0') //读到字符为0时,在霍夫曼树中表示为它的左孩子f=HT[f].lchild;if(!HT[f].lchild) //当读到的结点为叶子结点时,将叶子结点代表的字符输出{fputc(HT[f].ch,P2);f=2*n-1;}}fclose(P1);fclose(P2);}void menu(){printf("1.建立霍夫曼树");printf("2.编码\n");printf("3.译码\n");printf("0.结束\n");}int main(void){int n,i,m;HuffmanTree HT;HuffmanCode HC;do{menu();printf("你想要进行的操作:\n");scanf("%d",&n);switch(n){case 1:{printf("请输入字符集大小:");scanf("%d",&m);char *Charset=(char *)malloc(m*sizeof(char)); //为字符集分配内存printf("请输入%d个字符:",m);getchar();for(i=0;i<m;i++){scanf("%c",&Charset[i]);getchar();}int *weight=(int*)malloc(m*sizeof(int)); //为权值数组分配内存printf("输入对应的%d个权值:",m);for(i=0;i<m;i++){scanf("%d",&weight[i]);getchar();}HuffmanBiTree(HT,Charset,weight,m);}break;case 2:{printf("字符集的大小:");scanf("%d",&m);FILE *fp;if((fp=fopen("Hfmtree.txt","r"))==NULL){printf("file open error");exit(1);}int i;HT=(HuffmanTree)malloc((2*m)*sizeof(HTNode));//需从文件中读入已经写好的霍夫曼树for(i=1;i<=2*m-1;i++){fscanf(fp,"%c,%d,%d,%d,%d",&HT[i].ch,&HT[i].weight,&HT[i].parent,&HT[i]. lchild,&HT[i].rchild);//将文件中字符和整型数据赋给结构体数组HTfgetc(fp); //消除霍夫曼树文件中的换行符}HuffmanBicode(HC,m,HT);CodingFile(HT,HC,m);break;}case 3:{printf("字符集的大小:");scanf("%d",&m);FILE *fp;if((fp=fopen("Hfmtree.txt","r"))==NULL){printf("file open error");exit(1);}int i;HT=(HuffmanTree)malloc((2*m)*sizeof(HTNode));for(i=1;i<=2*m-1;i++){fscanf(fp,"%c,%d,%d,%d,%d",&HT[i].ch,&HT[i].weight,&HT[i].parent,&HT[i]. lchild,&HT[i].rchild);fgetc(fp);}Decoding(HT,m);break;}case 0:break;default:break;}}while(n!=0);system("pause");return 0;}调试分析:此为开始界面,选择你要进行的操作的编号(我们应该先建立霍夫曼树): 此时霍夫曼树已经建成,可以关闭窗口并在hfmtree.text里查看.接下来我们要对从文件读入的字符进行编码,先在当前目录下新建一个名为success.txt的文本,输入要进行编码的字符:THIS IS MYPROGRAM然后再次运行程序,选择操作2:此时编码已经完成并已经存入了coding.txt中,打开coding.txt可以看到:此时可以进行译码操作:再次打开程序,选择操作3:此时译码结果已经存在于decoding.txt中,打开译码文件,此时已经实现大部分功能.八、实验心得通过这次上机实验熟练了文件的操作,掌握fgetc(fp),fscanf(fp)的区别,fputc(fp)和fprintf(fp)的区别…注意细节,像拼写错误节应该避免,尽量用通俗易懂的标示符定义函数、变量等,特别注意变量应该先定义再使用。