霍夫曼树实验报告

合集下载

霍夫曼树实验报告

霍夫曼树实验报告

一、实验目的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. 实验分析通过实验,我们可以发现霍夫曼树在数据压缩方面具有较好的效果。

霍夫曼编码设计实验报告

霍夫曼编码设计实验报告

一、实验目的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赫夫曼编码及应用

实验报告课程名称:数据结构实验名称:赫夫曼编码及应用院(系):计算机与通信工程学院专业班级:计算机科学与技术姓名:学号:指导教师: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霍夫曼树

实验四数据结构与程序设计专题实验报告赫夫曼树学院:物理与电子学院班级:电信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中。

哈夫曼树_实验报告

哈夫曼树_实验报告

一、实验目的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编码和解码算法

(规格为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版)哈夫曼树实验报告

实验报告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。

赫夫曼树实验报告

赫夫曼树实验报告

赫夫曼树实验报告赫夫曼树实验报告引言:赫夫曼树是一种用于数据压缩的重要算法,它通过构建一棵二叉树来实现对数据的编码和解码。

本次实验旨在通过实际操作,深入了解赫夫曼树的原理和应用,并验证其在数据压缩中的有效性。

一、实验背景数据压缩在现代信息技术中起着至关重要的作用。

随着数据量的不断增加,如何有效地压缩数据成为了一个迫切的问题。

赫夫曼树作为一种经典的数据压缩算法,具有较高的压缩比和较快的解压速度,因此备受关注。

二、实验目的1. 了解赫夫曼树的原理和构建方法;2. 掌握赫夫曼编码的过程和步骤;3. 验证赫夫曼树在数据压缩中的有效性。

三、实验过程1. 构建赫夫曼树首先,我们需要统计待压缩数据中各个字符的出现频率。

然后,按照频率从小到大的顺序,将字符构建成一棵二叉树。

具体构建方法为:每次选取频率最低的两个字符,将它们作为左右子节点,生成一个新的节点,该节点的频率为左右子节点频率之和。

重复此过程,直到所有字符都被构建成树的节点。

2. 进行赫夫曼编码在赫夫曼树构建完成后,我们需要对每个字符进行编码。

编码的规则是:向左走为0,向右走为1。

从根节点开始,对每个字符进行路径搜索,直到找到对应的叶子节点,记录下路径上的0和1,即为该字符的编码。

3. 数据压缩与解压缩利用赫夫曼编码,我们可以对待压缩数据进行压缩。

将每个字符替换为对应的编码后,将所有编码拼接起来,即可得到压缩后的数据。

解压缩则是将编码根据赫夫曼树进行反向解码,得到原始数据。

四、实验结果通过实验,我们将不同类型的数据进行了压缩和解压缩,并与原始数据进行了对比。

结果表明,赫夫曼树在数据压缩中表现出色,能够显著减小数据的大小,同时保持数据的完整性。

五、实验总结赫夫曼树作为一种高效的数据压缩算法,具有广泛的应用前景。

通过本次实验,我们深入了解了赫夫曼树的原理和构建方法,并验证了其在数据压缩中的有效性。

赫夫曼树的应用不仅可以提高数据传输的效率,还可以节省存储空间,对于大数据时代的到来具有重要意义。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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)的区别…注意细节,像拼写错误节应该避免,尽量用通俗易懂的标示符定义函数、变量等,特别注意变量应该先定义再使用。

相关文档
最新文档