哈夫曼(huffman)编译码器课程设计
哈夫曼编码译码器课程设计
![哈夫曼编码译码器课程设计](https://img.taocdn.com/s3/m/8c4a0acb7d1cfad6195f312b3169a4517723e5b1.png)
哈夫曼编码译码器课程设计1.哈夫曼编码是一种有效的数据压缩算法,通过将最常用的字符编码为较短的比特串,最大限度地减少了存储空间。
本文档介绍一个哈夫曼编码译码器的设计和实现,该译码器可以实现从原始文本到哈夫曼编码的转换,并且可以从哈夫曼编码还原出原始文本。
2. 设计和实现本译码器的开发采用Python语言,主要分为两部分:哈夫曼编码和译码两部分。
2.1 哈夫曼编码哈夫曼编码的过程主要分为两步:1.统计每个字符出现的频率,并生成一个频率表。
2.根据频率表生成哈夫曼树,并生成相应的编码表。
以下是用于生成哈夫曼编码的Python代码:import heapqfrom collections import defaultdictclass Node:def__init__(self, freq, char=None, left=None, right=None): self.freq = freqself.char = charself.left = leftself.right = rightdef__lt__(self, other):return self.freq < other.freqdef__eq__(self, other):return self.freq == other.freqdef build_tree(data):freq = defaultdict(int)for char in data:freq[char] +=1q = [Node(freq[char], char) for char in freq]heapq.heapify(q)while len(q) >1:left = heapq.heappop(q)right = heapq.heappop(q)parent = Node(left.freq + right.freq, left.char + right.char, l eft, right)heapq.heappush(q, parent)return q[0]def generate_codes(node, current_code='', codes={}):if node is None:returnif node.char is not None:codes[node.char] = current_codegenerate_codes(node.left, current_code +'0', codes)generate_codes(node.right, current_code +'1', codes)return codes通过调用build_tree()函数来生成哈夫曼树,并调用generate_codes()函数来生成编码表。
哈夫曼编码与译码课程设计
![哈夫曼编码与译码课程设计](https://img.taocdn.com/s3/m/5eecbe958e9951e79a892787.png)
目录第1章需求分析 (1)第2章总体设计 (1)第3章抽象数据类型定义 (2)3.1 哈夫曼编码与译码抽象数据类型的设计 (2)第4章详细设计 (2)4.1 工程视图 (2)4.2 类图视图 (3)4.3 函数的调用关系 (3)4.4 主程序流程图 (4)4.5 主要算法的流程图 (5)第5章测试 (7)第6章总结 (8)附录:程序代码 (9)第1章需求分析Huffman编码和译码根据给定的字符集和各字符的频率值,求出其中给定字符Huffman编码,并针对一段文本(定义在该字符集上)进行编码和译码,实现一个Huffman编码/译码系统。
要求设计类(或类模板)来描述Huffman树及其操作,包含必要的构造函数和析构函数,以及其他能够完成如下功能的成员函数:求Huffman编码输入字符串,求出编码输入一段编码,实现译码并设计主函数测试该类。
第2章总体设计图2.1主函数:对输入的字符段进行存储,并对字符数和对应的权值(字符个数)进行统计存储。
哈夫曼树初始化函数:对给定的字符数和权值,创建一棵哈夫曼树。
权值大小比较函数:找到每次所给集合的最小值和次小值,并返回给哈夫曼树初始化函数。
哈夫曼树编码函数:对创建的哈夫曼树,为左孩子的赋值为0,右孩子赋值为1,然后对叶子结点依次编码。
哈夫曼树译码函数:对输入的01二进制数一一与叶子结点的编码依次比较匹配。
第3章抽象数据类型定义3.1哈夫曼编码与译码抽象数据类型的设计enum Child{none,lchild,rchild}; //采用枚举,标记是左孩子还是右孩子class element //元素类{public://类的公有成员elememt(); //构造函数void change(char l,char *c,int p,Child h,int w) //对对象进行修改操作void getparent(int p) //对父结点的值进行修改操作void geta(Child h) //对孩子结点进行修改操作void getweight(int w) //对权值进行修改操作int returnweight() //返回权值操作friend void Select(element h[],int k,int *a,int *b);//友元函数的声明friend void HuffmanTreeCode(element HT[]);friend void HuffmanTreeYima(element huff[],char cod[],int b);private://类的私有成员char letter,*code; //letter为字符,*code指向编码字符串int weight; //权值int parent; //父结点Child a; //为父结点的左孩子还是右孩子};第4章详细设计4.1工程视图图4.1工程视图4.2 类图视图图4.2类图视图4.3 函数的调用关系 如下图:图4.3函数调用关系图主函数main()哈夫曼初始化函数 InitHuffmanTree () 寻找最小和次小结点函数 Select() 字符编码函数 HuffmanTreeCode () 字符译码函数 HuffmanTreeYima ()4.4主程序流程图4.5主要算法的流程图图4.5.1哈夫曼编码函数图4.5.2哈夫曼译码函数图5.1哈夫曼编码与译码这次课程设计写得比较仓促,程序许多处仍需要完善和修改。
数据结构课程设计哈夫曼编码译码器
![数据结构课程设计哈夫曼编码译码器](https://img.taocdn.com/s3/m/d6542e85c1c708a1284a4481.png)
哈夫曼编码译码器哈夫曼编码译码器a)需求分析:一个完整的系统应具有以下功能:(l)I:初始化。
从终端读入字符集大小n,及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree中。
(2)C:编码。
利用已建好的哈夫曼树(如不在内存,则从文件hfmtree 中读入),对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中。
(3)D:编码。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
(4)P:印代码文件。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(5)T:印哈夫曼树。
将已在内存中的哈夫曼树以直观的方式 (树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint 中可以根据题目要求把程序划成5个模块,设计成菜单方式,每次执行一个模块后返回菜单。
除了初始化(I)过程外,在每次执行时都经过一次读取磁盘文件数据。
这是为了如果在程序执行后一直没有进行初始化(I)过程,为了能使后面的操作顺利进行,可以通过读取旧的数据来进行工作。
比如:如果程序的工作需要的字符集和权值数据是固定的,只要在安装程序时进行一次初始(I)化操作就可以了。
在再次运行程序时,不管进行那项操作都可以把需要的数据读入到内存。
b)概要设计本程序主要用到了三个算法。
(1)哈夫曼编码在初始化(I)的过程中间,要用输入的字符和权值建立哈夫曼树并求得哈夫曼编码。
先将输入的字符和权值存放到一个结构体数组中,建立哈夫曼树,将计算所得的哈夫曼编码存储到另一个结构体数组中。
(2)串的匹配在编码(D)的过程中间,要对已经编码过的代码译码,可利用循环,将代码中的与哈夫曼编码的长度相同的串与这个哈夫曼编码比较,如果相等就回显并存入文件。
(3)二叉树的遍历在印哈夫曼树(T)的中,因为哈夫曼树也是二叉树,所以就要利用二叉树的先序遍历将哈夫曼树输出c)详细设计构造树的方法如下:初始化:每个字符就是一个结点,字符的频度就是结点的权;1、将结点按频度从小到大排序;2、选取频度最小的两个结点,以它们为儿子,构造出一个新的结点;新结点的权值就是它两个儿子的权值之和;构造之后,从原来的结点序列里删除刚才选出的那两个结点,但同时将新生成的结点加进去;3、如果结点序列里只剩下一个结点,表示构造完毕,退出。
哈夫曼编译码器课程设计报告(完整版)
![哈夫曼编译码器课程设计报告(完整版)](https://img.taocdn.com/s3/m/633f06fab0717fd5370cdc19.png)
XXX学院本科数据结构课程设计总结报告设计题目:实验一、哈夫曼编/译码器学生姓名:XXX系别:XXX专业:XXX班级:XXX学号:XXX指导教师:XXX XXX2012年6 月21日xxx学院课程设计任务书题目一、赫夫曼编译码器专业、班级xxx学号xxx 姓名xxx主要内容、基本要求、主要参考资料等:1. 主要内容利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。
对于双工信道(既可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼的编/译码系统。
2. 基本要求系统应具有以下功能:(1)C:编码(Coding)。
对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中,将以此建好的哈夫曼树存入文件HuffmanTree中(2)D:解码(Decoding)。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入textfile中。
(3)P:打印代码文件(Print)。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(4)T:打印哈夫曼树(Tree Printing)。
将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
3. 参考资料:数据结构(C语言版)严蔚敏、吴伟民编著;数据结构标准教程胡超、闫宝玉编著完成期限:2012年6月21 日指导教师签名:课程负责人签名:2012年 6月 21 日一、设计题目(任选其一)实验一、哈夫曼编/译码器二、实验目的1巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;2 深化对算法课程中基本概念、理论和方法的理解;3 巩固构造赫夫曼树的算法;4 设计试验用程序实验赫夫曼树的构造。
huffman哈夫曼树编码译码课程设计报告
![huffman哈夫曼树编码译码课程设计报告](https://img.taocdn.com/s3/m/bd2cffa859eef8c75ebfb301.png)
数据结构课程设计信息科学与工程学院:学院计算机科学与技术专业:1601 计卓级:班号:学:学生姓名指导教师:23/ 1年月日题目名称一、实验内容哈夫曼编码译码系统【问题描述】用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼码的编/译码系统。
【基本要求】1)初始化。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树。
2)编码。
利用已建好的哈夫曼树对输入英文进行编码,编码结果存储在数组中。
3)译码。
利用已建好的哈夫曼树将数组中的代码进行译码,结果存入一个字符数组。
4)输出编码。
将编码结果显示在终端上,每行50个代码。
5)输出哈夫曼树。
将哈夫曼树以直观的方式(树或凹入表形式)显示出来。
【实现提示】用户界面可以设计为“菜单”方式,再加上一个“退出”功能。
请用户键入一个选择功能符。
此功能执行完毕后再显示此菜单,直至某次用户选择了“退出”为止。
参考教材P240-246【选做内容】将哈夫曼树保存到文件中,编码和译码的结果也分别存放在两个文本文件中。
23/ 2二、数据结构设计储存结构struct HNodeType {//字符结构体类型int weight;//权int parent;//双亲位置int lchild;//左孩子int rchild;//右孩子char inf;// 字符};struct HcodeType {存储编码int bit[MaxBit];// int start;// 起始位置};三、算法设计1、在构造哈夫曼树时,设计一个结构体数组HuffNode保存哈夫曼树中各结点的信息,根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有2n-1个结点,所以数组HuffNode的大小设置为2n-1。
大数据结构课程设计哈夫曼编码译码器
![大数据结构课程设计哈夫曼编码译码器](https://img.taocdn.com/s3/m/eddf5dcf6294dd88d0d26b34.png)
题目一:哈夫曼编码与译码一、任务设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。
要求:1) 将权值数据存放在数据文件(文件名为data.txt,位于执行程序的当前目录中) ;2) 初始化:键盘输入字符集统计字符权值、自定义26个字符和26个权值、统计文件中一篇英文文章中26个字母,建立哈夫曼树;3) 编码:利用建好的哈夫曼树生成哈夫曼编码;4) 输出编码(首先实现屏幕输出,然后实现文件输出);5)译码(键盘接收编码进行译码、文件读入编码进行译码);6) 界面优化设计。
二、流程图主菜单1.建立字符权值2.建立并输出哈夫曼树3.建立并查看哈弗曼编码4.编码与译码0.退出系统1.从键盘输入字符集统计2.从文件读入字符集统计权值3.自定义字符及权值0.返回上级菜单输出哈夫曼树并保存至文件“哈夫曼树。
t xt”1.编码2.译码0.返回上级菜单1.从键盘输入字符集进行编码2.从文件读入字符集进行编码1.从键盘输入编码进行译码2.从文件读入编码进行译码0.返回上级菜单0.返回上级菜单三、代码分解//头文件#include<stdio.h>#include<string.h>#include<stdlib.h>#include <conio.h>#define N 1000#define M 2*N-1#define MAXcode 6000//函数声明void count(CHar &ch,HTNode ht[]);void editHCode(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); //编码函数void printyima(HTNode ht[],HCode hcd[],int n,char bianma[]); //译码函数void creatHT(HTNode ht[],int n);void CreateHCode (HTNode ht[],HCode hcd[],int n);void DispHCode(HTNode ht[],HCode hcd[],int n);void input_key(CHar &ch);void input_file(CHar &ch);void input_cw(HTNode ht[]);void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]);void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]);void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]);void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]);void creat_cw();void bianmacaidan();void yimacaidan();void bianmayima();int caidan();//结构体typedef struct{char data;int parent;int weight;int lchild;int rchild;}HTNode;typedef struct{char cd[N];int start;}HCode;typedef struct{char s[N];int num;}CHar;CHar ch;HTNode ht[M];HCode hcd[N];//主函数int main(){int xh;while(1){system("color 1f"); //操作菜单背景颜色xh=caidan(); //调用菜单函数switch(xh) //switch语句{case 1:system("cls");creat_cw();break;case 2:system("cls");creatHT(ht,n);break;case 3:system("cls");CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);break;case 4:system("cls");bianmayima();break;case 0:system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t\t感谢使用本系统!\n\n\n\n\n\n\n \t\t\t");exit(0);default:system("cls");putchar('\a');printf("\n\t\t输入有误,请重新输入:\n");break;}}return 0;}//菜单函数int caidan() //菜单函数模块//{int xh;printf("\n\n\n");printf("\t\t 欢迎使用哈夫曼编码译码系统\n");printf("\t\t \n");printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");printf("\t\t*= =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 1.建立字符权值=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 2.建立并输出哈夫曼树=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 3.生成并查看哈夫曼编码=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 4.编码与译码=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 0.退出系统=*\n");printf("\t\t*= =*\n");printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d", &xh);return xh; //返回从键盘接收的选项}void bianmayima(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码与译码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianmacaidan();break;case 2:system("cls");yimacaidan();break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误,请重新输入:\n");break;}}}void yimacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 译码\n"); printf("\t\t \n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文件读入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");yima1(ht,hcd,n,bianma);break;case 2:system("cls");yima2(ht,hcd,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误,请重新输入:\n");break;}}}void bianmacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入字符集编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文件读入文章编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianma1(ht,hcd,ch,n,bianma);break;case 2:system("cls");bianma2(ht,hcd,ch,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误,请重新输入:\n");break;}}}void creat_cw(){int xh2;while(1){printf("\n\n\n\n\n");printf("\t\t 建立字符权值\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.从键盘输入字符集进行统计=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.从文件读入字符集统计=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 3.自定义字符权值=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh2);switch(xh2) //switch语句{case 1:system("cls");input_key(ch);break;case 2:system("cls");input_file(ch);break;case 3:system("cls");input_cw(ht);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误,请重新输入:\n");break;}}}//建立字符权值模块void input_key(CHar &ch){int i,j=0;char st[N];printf("请输入字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&st[i]);if(st[i]=='#'){st[i]='\0';break;}}strcpy(ch.s,st);ch.num=strlen(st);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_file(CHar &ch){int i;FILE*fp;char filename[20];printf("请输入要打开的文件名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}ch.num=strlen(ch.s);printf("读入成功!\n");printf("文件中的字符集为:%s\n",ch.s);fclose(fp);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_cw(HTNode ht[]){int i,w,s,j;char a;printf("要输入的字符总个数是?:");scanf("%d",&s);n=s;printf("请输入字符及其权值:\n");for(i=0;i<s;i++){printf("请输入第%d个字母:",i+1);scanf("%s",&a);ht[i].data=a;printf("请输入其权值:");scanf("%d",&w);ht[i].weight=w;}FILE *fp;if((fp=fopen("data.txt","w"))==0){printf("\n\t\t文件打开失败");return;}printf("\n定义权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<i;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文件“data.txt”!");fclose(fp);printf("输入完成,按任意键返回!");getch();system("cls");return;}//统计字符权值函数void count(CHar &ch,HTNode ht[]){int i,j,m=0;char c[N];int sum[N]={0};for(i=0;ch.s[i]!='\0';i++){for(j=0;j<m;j++)if(ch.s[i]==c[j]||(c[j]>='a'&&c[j]<='z'&&ch.s[i]+32==c[j])) break;if(j<m)sum[j]++;else{if(ch.s[i]>='A'&&ch.s[i]<='Z')c[j]=ch.s[i]+32;else c[j]=ch.s[i];sum[j]++;m++;}}for(i=0;i<m;i++){ht[i].data=c[i];ht[i].weight=sum[i];}n=m;FILE *fp;if((fp=fopen("data.txt","w"))==0){printf("\n\t\t文件打开失败");return;}printf("\n统计权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<m;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文件“data.txt”!");fclose(fp);}//构造哈夫曼树void creatHT(HTNode ht[],int n){FILE *fp;if((fp=fopen("哈夫曼树.txt","w"))==0){printf("\n\t\t文件打开失败");return;}int i,j,k,lnode,rnode;int min1,min2;for (i=0;i<2*n-1;i++)ht[i].parent=ht[i].lchild=ht[i].rchild=-1;for (i=n;i<2*n-1;i++){min1=min2=32767;lnode=rnode=-1;for(k=0;k<=i-1;k++)if(ht[k].parent==-1){if (ht[k].weight<min1){min2=min1;rnode=lnode;min1=ht[k].weight;lnode=k;}else if(ht[k].weight<min2){min2=ht[k].weight;rnode=k;}}ht[lnode].parent=i;ht[rnode].parent=i;ht[i].weight=ht[lnode].weight+ht[rnode].weight;ht[i].lchild=lnode;ht[i].rchild=rnode;}printf("建立huffman树成功!\n");printf("输出huffman树:\n");fprintf(fp,"输出huffman树:\n");printf("\t字符\t权值\t父节点\t 左子节点\t右子节点");fprintf(fp,"\t字符\t权值\t父节点\t 左子节点\t右子节点");for(j=1;j<i;j++){ printf("\n");fprintf(fp,"\n");printf("\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,ht[i]. lchild,ht[j].rchild);fprintf(fp,"\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,h t[i].lchild,ht[j].rchild);}printf("\n");printf("哈夫曼树已输出至文件“哈夫曼树.txt”!按任意键返回!");fclose(fp);getch();system("cls");return;}//生成哈夫曼编码void CreateHCode (HTNode ht[],HCode hcd[],int n){int i,f,c,j=0;HCode hc;for(i=0;i<n;i++){hc.start=n;c=i;hc.cd[hc.start--]='0';f=ht[i].parent;while(f!=-1){if (ht[f].lchild==c)hc.cd[hc.start--]='0';elsehc.cd[hc.start--]='1';c=f;f=ht[f].parent;}hc.start++;for(j=0;j<hc.start;j++)hc.cd[j]=' ';hcd[i]=hc;}}void DispHCode(HTNode ht[],HCode hcd[],int n) {FILE *fp;if((fp=fopen("哈夫曼编码.txt","w"))==0){printf("\n\t\t文件打开失败");return;}int i,k;int sum=0,m=0,j;printf("输出字符哈夫曼编码:\n");fputs("输出字符哈夫曼编码:\n",fp);for (i=0;i<n;i++){j=0;printf("%c:\t",ht[i].data);fprintf(fp,"\n%c:\t",ht[i].data);for (k=hcd[i].start;k<=n;k++){printf("%c",hcd[i].cd[k]);j++;fprintf(fp,"%c",hcd[i].cd[k]);}m+=ht[i].weight;sum+=ht[i].weight*j;printf("\n");}printf("\n哈夫曼编码已保存至文件“哈夫曼编码.txt!按任意键返回!”");fclose(fp);getch();system("cls");}//编码函数void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]){int i;char str[N];printf("请输入要编码的字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&str[i]);if(str[i]=='#'){str[i]='\0';break;}}strcpy(ch.s,str);ch.num=strlen(str);editHCode(ht,hcd,ch,n,bianma);getch();system("cls");return;}void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文件名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}ch.num=strlen(ch.s);printf("\n读入成功!\n");printf("文件中的字符集为:\n%s",ch.s);fclose(fp);editHCode(ht,hcd,ch,n,bianma);getch();system("cls");return;}//译码函数void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]){int i;char code[MAXcode];printf("请输入编码进行译码(以‘#’结束):\n");for(i=0;i<MAXcode;i++){scanf("%c",&code[i]);if(code[i]=='#'){code[i]='\0';break;}}strcpy(bianma,code);printyima(ht,hcd,n,bianma);printf("\n译码完成!按任意键返回!");getch();system("cls");return;}void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文件名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文件打开失败");return;}for(i=0;!feof(fp);i++){fread(&bianma[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文件中的编码是:%s\n",bianma);printyima(ht,hcd,n,bianma);printf("\n译码完成!按任意键返回!");getch();system("cls"); }四、调试结果主菜单建立字符权值选择2.从文件读入字符进行统计输入测试文件名“cs.txt”输出个字符权值建立哈夫曼树并输出至文件生成哈夫曼编码并保存至文件编码选择2.从文件读入字符集编码编码结果保存至文件译码选择2.从文件读入编码,读入上一步的编码译码完成,返回!退出系统。
哈夫曼编译码器课程设计报告(完整版)
![哈夫曼编译码器课程设计报告(完整版)](https://img.taocdn.com/s3/m/b642982ca26925c52dc5bf4a.png)
XXX学院本科数据结构课程设计总结报告设计题目:实验一、哈夫曼编/译码器学生:XXX系别:XXX专业:XXX班级:XXX学号:XXX指导教师:XXX XXX2012年6 月21日xxx学院课程设计任务书题目一、赫夫曼编译码器专业、班级xxx学号xxx xxx主要容、基本要求、主要参考资料等:1. 主要容利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低传输成本。
要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。
对于双工信道(既可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼的编/译码系统。
2. 基本要求系统应具有以下功能:(1)C:编码(Coding)。
对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中,将以此建好的哈夫曼树存入文件HuffmanTree中(2)D:解码(Decoding)。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入textfile中。
(3)P:打印代码文件(Print)。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(4)T:打印哈夫曼树(Tree Printing)。
将已在存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
3. 参考资料:数据结构(C语言版)严蔚敏、吴伟民编著;数据结构标准教程胡超、闫宝玉编著完成期限:2012年6月21 日指导教师签名:课程负责人签名:2012年 6月 21 日一、设计题目(任选其一)实验一、哈夫曼编/译码器二、实验目的1巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;2 深化对算法课程中基本概念、理论和方法的理解;3 巩固构造赫夫曼树的算法;4 设计试验用程序实验赫夫曼树的构造。
哈夫曼编译码器设计课设
![哈夫曼编译码器设计课设](https://img.taocdn.com/s3/m/40c5bfed81c758f5f61f671d.png)
目录目录 (1)摘要 (2)前言 (3)1.问题描述: (4)2.逻辑设计: (4)3.详细设计: (5)4.程序编码 (5)5.程序调试与测试 (7)6.结果分析 (7)7.软件的安装及使用说明 (8)设计总结 (10)致谢 (11)参考文献 (12)摘要本课程设计是为了让同学们了解学习数据结构的作用和意义。
数据结构是计算机科学与技术专业的专业基础课,是十分重要的课程。
所有的计算机系统软件和应用软件都要用到各种类型的数据结构。
因此,想要更好地运用计算机来解决实际问题,仅仅掌握几门计算机程序设计语言是远远难以应付当前众多复杂的课题,想要有效地使用计算机,充分发挥它的性能,还必须学习和掌握好数据结构的有关知识,打好数据结构这门课的扎实基础,对于学习计算机专业其它的课程,如操作系统、软件工程、编译原理、数据库、人工智能等十分有益。
树状结构简称为数,是一种以分支关系进行定义的层次结构,是十分重要的非线性数据结构,在计算机软件设计方面,有着广泛的应用。
在这个信息量发达的时代,随着社会的进步,信息不断地增多和更新,为了使信息更加快速、准确有效的传输,那就需要一个编码和解码的程序来完成。
关键词:数据结构、树状结构、编码和解码前言本课程设计要求完成发送端对待传送数据的编码和接收端对传送来的数据的译码。
要实现五个功能:接收原始数据、编码、译码、将编码和译码存档。
通过系统的提示建立赫夫曼树并对载入的原文件进行编码,并保存到指定的文件中,同时输出到屏幕。
另一方面,对原文件进行译码,并将译码的结果保存到指定的文件中,同时输到屏幕。
对于编码和译码的操作中的文件导入,分为键盘输入和文件输入两种。
1.问题描述:根据赫夫曼编码和解码算法,将指定的文件中的赫夫曼编码进行译码,并输出到文件中,还要实现对文件中支付的编码,并输出编码到文件中。
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
Huffman编码译码器
![Huffman编码译码器](https://img.taocdn.com/s3/m/bd2fa08471fe910ef12df848.png)
课程设计:Huffman编码/译码器一、任务描述任务:设计一个利用哈夫曼算法的编码和译码系统。
要求:建立一个文本文件,统计该文件中各字符频率,对各字符进行Huffman编码,将该文件翻译成Huffman编码文件,再将Huffman编码文件翻译成原文件。
“压缩文件”即:读文件、统计文件中的字符个数、对文件进行哈夫曼编码和译码、并将编码译码后的字符存储在文件中。
根据以上任务说明,设计数据结构,并设计程序完成功能。
二、问题分析分析设计课题的要求,要求编程实现以下功能:(1)创建最小Huffman树;(2)统计文件中个字符的个数(频率);(3)对个字符进行编码;(4)将原文件翻译成编码文件;(5)将编码文件翻译成原文件;(6)创建yuanwj.txt、yima.txt、out.txt三、数据结构设计选用二叉树链表实现。
有关的定义如下:typedef struct node //哈夫曼树节点的结构体定义{char data;int weight;int parent,lc,rc;}NODE;typedef struct abc{char ch;char str[20];int s;}ABC;四、功能设计(一)、主控菜单设计为实现编码译码的操作功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
程序运行后,给出4个菜单项的内容和输入提示,如下:1、键盘输入进行编码;2、读文件进行编码;3、译码;4、退出系统;(二)程序模块结构由课题要求可将程序划分为以下几个模块:(1)统计字符的频度tongji();(2)建立哈弗曼树haffman() ;(3)编码 huffmancode();(4)输入input();(5)输出output();(6)译码yima();(三)、函数调用关系其中main()是主函数,它进行菜单驱动,根据选择项0~3调用相应的函数。
main()函数使用switch循环实现重复选择。
哈夫曼编码译码器---课程设计报告.docx
![哈夫曼编码译码器---课程设计报告.docx](https://img.taocdn.com/s3/m/aeba3a5c856a561253d36f56.png)
目录目⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ (2)1 程的目的和意⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯32 需求分析⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯43 概要⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯4 4⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.85 分析和果⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯.11 6⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯127致⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯138附⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯13参考文献⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯..201课程设计目的与意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。
哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。
树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“ 1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。
通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。
电报通信是传递文字的二进制码形式的字符串。
但在信息传递时,总希望总长度尽可能最短,即采用最短码。
作为计算机专业的学生,我们应该很好的掌握这门技术。
在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。
在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。
这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试 C 程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。
数据结构课程设计哈夫曼编码译码器
![数据结构课程设计哈夫曼编码译码器](https://img.taocdn.com/s3/m/908cb3a1102de2bd97058802.png)
哈夫曼编码译码器哈夫曼编码译码器a)需求分析:一个完整的系统应具有以下功能:(l)I:初始化。
从终端读入字符集大小n,及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree中。
(2)C:编码。
利用已建好的哈夫曼树(如不在内存,则从文件hfmtree 中读入),对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中。
(3)D:编码。
利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
(4)P:印代码文件。
将文件codefile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件codeprint中。
(5)T:印哈夫曼树。
将已在内存中的哈夫曼树以直观的方式 (树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint 中可以根据题目要求把程序划成5个模块,设计成菜单方式,每次执行一个模块后返回菜单。
除了初始化(I)过程外,在每次执行时都经过一次读取磁盘文件数据。
这是为了如果在程序执行后一直没有进行初始化(I)过程,为了能使后面的操作顺利进行,可以通过读取旧的数据来进行工作。
比如:如果程序的工作需要的字符集和权值数据是固定的,只要在安装程序时进行一次初始(I)化操作就可以了。
在再次运行程序时,不管进行那项操作都可以把需要的数据读入到内存。
b)概要设计本程序主要用到了三个算法。
(1)哈夫曼编码在初始化(I)的过程中间,要用输入的字符和权值建立哈夫曼树并求得哈夫曼编码。
先将输入的字符和权值存放到一个结构体数组中,建立哈夫曼树,将计算所得的哈夫曼编码存储到另一个结构体数组中。
(2)串的匹配在编码(D)的过程中间,要对已经编码过的代码译码,可利用循环,将代码中的与哈夫曼编码的长度相同的串与这个哈夫曼编码比较,如果相等就回显并存入文件。
(3)二叉树的遍历在印哈夫曼树(T)的中,因为哈夫曼树也是二叉树,所以就要利用二叉树的先序遍历将哈夫曼树输出c)详细设计构造树的方法如下:初始化:每个字符就是一个结点,字符的频度就是结点的权;1、将结点按频度从小到大排序;2、选取频度最小的两个结点,以它们为儿子,构造出一个新的结点;新结点的权值就是它两个儿子的权值之和;构造之后,从原来的结点序列里删除刚才选出的那两个结点,但同时将新生成的结点加进去;3、如果结点序列里只剩下一个结点,表示构造完毕,退出。
哈夫曼编码译码课程设计报告
![哈夫曼编码译码课程设计报告](https://img.taocdn.com/s3/m/4e6d62977f1922791688e8c1.png)
哈夫曼编码译码课程设计报告《数据结构》课程设计——赫夫曼编码/译码器设计指导教师:李文书、周维达班级:10电信实验班学号:Q10600132姓名:王彬彬一、实验目的1、提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法。
2、熟悉掌握一门计算机语言,能够进行数据算法设计。
二、实验原理哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。
在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。
构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。
最简单的二进制编码方式是等长编码。
若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。
哈夫曼树课用于构造使电文的编码总长最短的编码方案。
主要流程图如下:三、实验步骤1:写好流程图,设计实验方案。
2:初始化,从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件HuofumanTree中。
3:编码。
利用已建好的哈夫曼树,对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
4:译码。
利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。
5:印代码文件(Print).将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
6:印哈夫曼树(Treeprinting).将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint 中。
具体函数如下:1:Initialization() 初始化2:Encoding() 编码3:Decoding() 译码4:Print_file() 打印代码文件5:search(k,j,p) 搜索二叉树6:Print_tree() 打印二叉树7:menu() 主菜单9:main() 主函数四、实验结果与分析(1)大致个人测试案例:主界面:初始化:Huofuman.txt初始化存入文件结果如下:编码结果如下:codefile.txt编码存入文件如下:译码结果如下:textfile.txt译码存入文件如下:打印结果如下:打印树结果如下:treeprint.txt存入文件结果如下:(2)本例测试案例_1已知某系统在通信联络中只可能出现八种字符,其频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计哈夫曼编码。
数据结构课程设计哈夫曼编码译码器
![数据结构课程设计哈夫曼编码译码器](https://img.taocdn.com/s3/m/88cc2679cdbff121dd36a32d7375a417866fc199.png)
题目一: 哈夫曼编码与译码一、任务设计一个运用哈夫曼算法的编码和译码系统, 反复地显示并解决以下项目, 直到选择退出为止。
规定:1) 将权值数据存放在数据文献(文献名为data.txt, 位于执行程序的当前目录中) ;2) 初始化:键盘输入字符集记录字符权值、自定义26个字符和26个权值、记录文献中一篇英文文章中26个字母, 建立哈夫曼树;3) 编码: 运用建好的哈夫曼树生成哈夫曼编码;4) 输出编码(一方面实现屏幕输出, 然后实现文献输出);5)译码(键盘接受编码进行译码、文献读入编码进行译码);6) 界面优化设计。
二、流程图三、代码分解 //头文献 #include<stdio.h> #include<string.h> #include<stdlib.h> #include <conio.h> #define N 1000 #define M 2*N-1 #define MAXcode 6000 //函数声明void count(CHar &ch,HTNode ht[]);void editHCode(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); //编码函数void printyima(HTNode ht[],HCode hcd[],int n,char bianma[]); //译码函数 void creatHT(HTNode ht[],int n);字符集记录符集记录权值 权值 至文献“哈夫曼树。
t xt” 菜单1.从键盘输入字符集进行编码2.从文献读入字符集进行编码1.从键盘输入编码进行译码2.从文献读入编码进行译码0.返回上级菜单 0.返回上级菜单void CreateHCode (HTNode ht[],HCode hcd[],int n);void DispHCode(HTNode ht[],HCode hcd[],int n);void input_key(CHar &ch);void input_file(CHar &ch);void input_cw(HTNode ht[]);void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]); void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]);void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]);void creat_cw();void bianmacaidan();void yimacaidan();void bianmayima();int caidan();//结构体typedef struct{char data;int parent;int weight;int lchild;int rchild;}HTNode;typedef struct{char cd[N];int start;}HCode;typedef struct{char s[N];int num;}CHar;CHar ch;HTNode ht[M];HCode hcd[N];//主函数int main(){int xh;while(1){system("color 1f"); //操作菜单背景颜色 xh=caidan(); //调用菜单函数switch(xh) //switch语句 {case 1:system("cls");creat_cw();break;case 2:system("cls");creatHT(ht,n);break;case 3:system("cls");CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);break;case 4:system("cls");bianmayima();break;case 0:system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t\t感谢使用本系统!\n\n\n\n\n\n\n \t\t\t");exit(0);default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}return 0;}//菜单函数int caidan() //菜单函数模块//{int xh;printf("\n\n\n");printf("\t\t 欢迎使用哈夫曼编码译码系统\n");printf("\t\t \n");printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");printf("\t\t*= =*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n");printf("\t\t*= 1.建立字符权值=*\n");printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 2.建立并输出哈夫曼树=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 3.生成并查看哈夫曼编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 4.编码与译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*= =*\n"); printf("\t\t*= 0.退出系统=*\n"); printf("\t\t*= =*\n"); printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d", &xh);return xh; //返回从键盘接受的选项}void bianmayima(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码与译码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n");printf("\t\t*= 1.编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianmacaidan();break;case 2:system("cls");yimacaidan();break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void yimacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 译码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文献读入编码进行译码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");yima1(ht,hcd,n,bianma);break;case 2:system("cls");yima2(ht,hcd,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void bianmacaidan(){int xh;while(1){printf("\n\n\n\n\n");printf("\t\t 编码\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.键盘输入字符集编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.文献读入文章编码=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh);switch(xh) //switch语句{case 1:system("cls");bianma1(ht,hcd,ch,n,bianma);break;case 2:system("cls");bianma2(ht,hcd,ch,n,bianma);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}void creat_cw(){int xh2;while(1){printf("\n\n\n\n\n");printf("\t\t 建立字符权值\n"); printf("\t\t \n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 1.从键盘输入字符集进行记录=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 2.从文献读入字符集记录=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 3.自定义字符权值=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\t\t*= 0.返回上级菜单=*\n"); printf("\t\t*= *=*=*=*=*=*=*=*=*=*=*=*=*=*=* =*\n"); printf("\n\t\t请输入序号进行选择:");scanf("%d",&xh2);switch(xh2) //switch语句{case 1:system("cls");input_key(ch);break;case 2:system("cls");input_file(ch);break;case 3:system("cls");input_cw(ht);break;case 0:system("cls");return;default:system("cls");putchar('\a');printf("\n\t\t输入有误, 请重新输入:\n");break;}}}//建立字符权值模块void input_key(CHar &ch){int i,j=0;char st[N];printf("请输入字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&st[i]);if(st[i]=='#'){st[i]='\0';break;}}strcpy(ch.s,st);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_file(CHar &ch){int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文献中的字符集为:%s\n",ch.s);fclose(fp);count(ch,ht);printf("按任意键返回!");getch();system("cls");return;}void input_cw(HTNode ht[]){int i,w,s,j;char a;printf("要输入的字符总个数是?:");scanf("%d",&s);n=s;printf("请输入字符及其权值:\n");for(i=0;i<s;i++){printf("请输入第%d个字母:",i+1);scanf("%s",&a);ht[i].data=a;printf("请输入其权值:");scanf("%d",&w);ht[i].weight=w;}FILE *fp;if((fp=fopen("data.txt","w"))==0){printf("\n\t\t文献打开失败");return;}printf("\n定义权值成功!\n\n");printf("各字符及其权值为:\n\n");fprintf(fp,"各字符及其权值为:\n");printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<i;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight); }printf("\n");printf("\n字符权值已输出至文献“data.txt”!");fclose(fp);printf("输入完毕, 按任意键返回!");getch();system("cls");return;}//记录字符权值函数void count(CHar &ch,HTNode ht[]){int i,j,m=0;char c[N];int sum[N]={0};for(i=0;ch.s[i]!='\0';i++){for(j=0;j<m;j++)if(ch.s[i]==c[j]||(c[j]>='a'&&c[j]<='z'&&ch.s[i]+32==c[j])) break;if(j<m)sum[j]++;else{if(ch.s[i]>='A'&&ch.s[i]<='Z')c[j]=ch.s[i]+32;else c[j]=ch.s[i];sum[j]++;m++;}}for(i=0;i<m;i++){ht[i].data=c[i];ht[i].weight=sum[i];}n=m;FILE *fp;if((fp=fopen("data.txt","w"))==0) {printf("\n\t\t文献打开失败"); return;}printf("\n记录权值成功!\n\n"); printf("各字符及其权值为:\n\n"); fprintf(fp,"各字符及其权值为:\n"); printf(" 字符\t权值");fprintf(fp," 字符\t权值");for(j=0;j<m;j++){ printf("\n");fprintf(fp,"\n");printf(" %-8c%-8d",ht[j].data,ht[j].weight);fprintf(fp," %-8c%-8d%",ht[j].data,ht[j].weight);}printf("\n");printf("\n字符权值已输出至文献“data.txt”!");fclose(fp);}//构造哈夫曼树void creatHT(HTNode ht[],int n){FILE *fp;if((fp=fopen("哈夫曼树.txt","w"))==0){printf("\n\t\t文献打开失败");return;}int i,j,k,lnode,rnode;int min1,min2;for (i=0;i<2*n-1;i++)ht[i].parent=ht[i].lchild=ht[i].rchild=-1;for (i=n;i<2*n-1;i++){min1=min2=32767;lnode=rnode=-1;for(k=0;k<=i-1;k++)if(ht[k].parent==-1){if (ht[k].weight<min1){min2=min1;rnode=lnode;min1=ht[k].weight;lnode=k;}else if(ht[k].weight<min2){min2=ht[k].weight;rnode=k;}}ht[lnode].parent=i;ht[rnode].parent=i;ht[i].weight=ht[lnode].weight+ht[rnode].weight;ht[i].lchild=lnode;ht[i].rchild=rnode;}printf("建立huffman树成功!\n");printf("输出huffman树:\n");fprintf(fp,"输出huffman树:\n");printf("\t字符\t权值\t父节点\t 左子节点\t右子节点");fprintf(fp,"\t字符\t权值\t父节点\t 左子节点\t右子节点");for(j=1;j<i;j++){ printf("\n");fprintf(fp,"\n");printf("\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,ht[i]. lchild,ht[j].rchild);fprintf(fp,"\t %-8c%-8d%-10d%-14d%-10d",ht[j].data,ht[j].weight,ht[j].parent,h t[i].lchild,ht[j].rchild);}printf("\n");printf("哈夫曼树已输出至文献“哈夫曼树.txt”!按任意键返回!");fclose(fp);getch();system("cls");return;}//生成哈夫曼编码void CreateHCode (HTNode ht[],HCode hcd[],int n){int i,f,c,j=0;HCode hc;for(i=0;i<n;i++){hc.start=n;c=i;hc.cd[hc.start--]='0';f=ht[i].parent;while(f!=-1){if (ht[f].lchild==c)hc.cd[hc.start--]='0';elsehc.cd[hc.start--]='1';c=f;f=ht[f].parent;}hc.start++;for(j=0;j<hc.start;j++)hc.cd[j]=' ';hcd[i]=hc;}}void DispHCode(HTNode ht[],HCode hcd[],int n) {FILE *fp;if((fp=fopen("哈夫曼编码.txt","w"))==0){printf("\n\t\t文献打开失败");return;}int i,k;int sum=0,m=0,j;printf("输出字符哈夫曼编码:\n"); fputs("输出字符哈夫曼编码:\n",fp); for (i=0;i<n;i++){j=0;printf("%c:\t",ht[i].data);fprintf(fp,"\n%c:\t",ht[i].data);for (k=hcd[i].start;k<=n;k++){printf("%c",hcd[i].cd[k]);j++;fprintf(fp,"%c",hcd[i].cd[k]); }m+=ht[i].weight;sum+=ht[i].weight*j;printf("\n");}printf("\n哈夫曼编码已保存至文献“哈夫曼编码.txt!按任意键返回!”");fclose(fp);getch();system("cls");}//编码函数void bianma1(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]){int i;char str[N];printf("请输入要编码的字符集(以‘#’结束):\n");for(i=0;i<N;i++){scanf("%c",&str[i]);if(str[i]=='#'){str[i]='\0';break;}}strcpy(ch.s,str);ch.num=strlen(str);editHCode(ht,hcd,ch,n,bianma);getch();system("cls");}void bianma2(HTNode ht[],HCode hcd[],CHar &ch,int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&ch.s[i],sizeof(char),1,fp);}ch.num=strlen(ch.s);printf("\n读入成功!\n");printf("文献中的字符集为:\n%s",ch.s);fclose(fp);editHCode(ht,hcd,ch,n,bianma);system("cls");return;}//译码函数void yima1(HTNode ht[],HCode hcd[],int n,char bianma[]) {int i;char code[MAXcode];printf("请输入编码进行译码(以‘#’结束):\n");for(i=0;i<MAXcode;i++){scanf("%c",&code[i]);if(code[i]=='#'){code[i]='\0';break;}}strcpy(bianma,code);printyima(ht,hcd,n,bianma);printf("\n译码完毕!按任意键返回!");getch();system("cls");return;}void yima2(HTNode ht[],HCode hcd[],int n,char bianma[]) {int i;FILE*fp;char filename[20];printf("请输入要打开的文献名(*.txt):");scanf("%s",&filename);if((fp=fopen(filename,"r"))==NULL){printf("\n\t\t文献打开失败");return;}for(i=0;!feof(fp);i++){fread(&bianma[i],sizeof(char),1,fp);}printf("读入成功!\n");printf("文献中的编码是:%s\n",bianma);printyima(ht,hcd,n,bianma);printf("\n译码完毕!按任意键返回!");getch();system("cls");}四、调试结果主菜单建立字符权值选择2.从文献读入字符进行记录输入测试文献名“cs.txt”输出个字符权值建立哈夫曼树并输出至文献生成哈夫曼编码并保存至文献编码选择2.从文献读入字符集编码编码结果保存至文献译码选择2.从文献读入编码, 读入上一步的编码译码完毕, 返回!退出系统。
哈夫曼编码译码器课程设计
![哈夫曼编码译码器课程设计](https://img.taocdn.com/s3/m/b969876ad15abe23492f4d9e.png)
fw)屛矗久多it耳迦WANG JNSTITUII L Ul- 11UDWX课程设计说明书课程名称:数据结构与算法____________ 设计题目:哈夫曼编译码器院系:计算机科学与信息工程学院学生姓名:____________ 刘文杰______________ 学号:____________ 16031210229 ___________ 专业班级:________软件工程16-2 ___________ 指导教师:____________ 孙高飞______________2017年12月11日课程设计任务书哈夫曼编译码器摘要:采用哈夫曼编码思想实现对字符串的编码,以及对编码的解码。
字符串的长度不小于5000 字节。
读取要编码的文本文件,将文件的内容进行编码,生成新的文件对编码文件进行解码,获得文本文件。
将译码的文本文件和原文件进行比较,恢复文件和原文件必须完全一致。
关键词:构建哈夫曼树哈弗曼编码哈夫曼译码字符串编码打印编码函数目录1. ...................................................................... 设计背景. 11.1 哈夫曼树的介绍 (1)1.2 设计的作用、目的 (1)1.3 设计任务及要求 (2)2. 设计方案. (2)2.1 实验内容 (2)2.2 操作思路 (2)2.3 基本操作 (3)3. 方案实施. (4)3.1 C 语言编程 (4)3.2 程序介绍 (12)3.3 程序流程图以及说明 (13)图3 主程序流程图 (13)4. 结果与结论. (14)4.1 程序运行结果 (14)4.2 总结 (16)5. 收获与致谢. (17)6. 参考文献. (17)1. 设计背景1.1 哈夫曼树的介绍Huffman Tree ,中文名是哈夫曼树或霍夫曼树或者赫夫曼树,它是最优二叉树。
定义:给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。
数据结构课程设计哈夫曼编码译码器
![数据结构课程设计哈夫曼编码译码器](https://img.taocdn.com/s3/m/3e586f2c6ad97f192279168884868762caaebbd8.png)
数据结构课程设计哈夫曼编码译码器个节点的权值、父节点、左孩子和右孩子,然后通过选择最小的两个节点合并,构建Huffman树;3:Huffman编码:通过遍历Huffman树,对每个叶子节点进行编码,将编码结果存入新的文件中;4:译码:读取存放Huffman编码的文件,通过遍历Huffman树进行译码,将译码结果存入新的文件中;5:结果验证:比较原文件和译码结果文件的内容是否一致,输出结果;3.函数说明1:CrtHuffmanTree():创建Huffman树;2:HuffmanCoding():对Huffman树进行遍历,生成Huffman编码;3:HuffmanDecoding():对Huffman编码进行译码,生成原文件内容;4:CompareFile():比较原文件和译码结果文件的内容是否一致;五、详细设计1.统计字符频率:定义结构体typedef struct strchar data;char num;str;其中data域存放字符名称,num域存放字符出现频率,读取文件ywq1.txt,通过循环比较将结果赋入S2[128]中;2.创建Huffman树:定义结构体typedef structchar data;int weight;int parent;int lchild;int rchild;HTNode,HuffmanTree[M+1];作为Huffman树存储节点类型,调用CrtHuffmanTree()函数,初始化各个节点的权值、父节点、左孩子和右孩子,然后通过选择最小的两个节点合并,构建Huffman树;3.Huffman编码:通过遍历Huffman树,对每个叶子节点进行编码,将编码结果存入新的文件中;4.译码:读取存放Huffman编码的文件,通过遍历Huffman树进行译码,将译码结果存入新的文件中;5.结果验证:比较原文件和译码结果文件的内容是否一致,输出结果;六、测试1.测试数据测试文件:ywq1.txt(包含英文字母、数字和符号)2.测试结果测试结果正确,能够正确地对文件进行Huffman编码和译码,生成的译码结果文件与原文件内容一致;七、总结通过本次课程设计,我深入了解了Huffman编码/译码器的实现原理和过程,掌握了Huffman树的创建、存储和遍历方法,提高了动手能力,同时也为数据压缩问题提供了一种有效的解决方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
兰州商学院陇桥学院工学系课程设计报告设计题目:哈夫曼(huffman)编译码器系别:专业 (方向):年级、班:学生姓名:学生学号:指导教师:年月日目录哈夫曼(huffman )编译码器 (3)一、编译码器开发的背景 (3)二、系统的分析与设计 (3)(一)系统功能要求 (3)(二)系统模块结构设计 (4)三、系统的设计与实现 (6)(一)main() (6)(二)运算 (7)1. 权值运算quanzhi() (7)2. 印二叉树函数huffmantree( ) (7)3.编译码运算huffmancode() (9)4. 输出运算 shuchu() (9)四、系统测试 (10)(一)测试主函数 (10)(二)测试印二叉树函数 (10)(三)测试译码运算函数 (11)五、总结 (12)六、附件(代码、部分图表) (13)哈夫曼(huffman )编译码器一、编译码器开发的背景利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
二、系统的分析与设计(一)系统功能要求一个完整的系统应具有以下功能: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中。
(二)系统模块结构设计通过对系统功能的分析,哈夫曼(huffman)编译码器功能如图(1)所示。
图(1)哈夫曼(huffman)编译码器功能图通过上图的功能分析,把整个系统分为四个模块:1.初始化模块,该模块主要实现:输入二叉树的结点数,以及要加密的句子,建立哈夫曼树。
2.输出二叉树模块,该运算模块主要实现:将输入的字符串中每个字符出现的次数当作权值,建立二叉树,将二叉树的parent,weight,lchild,rchild输出。
3.译码模块,该操作主要实现:对编码后的代码进行译码,然后输出。
4.输出模块,该操作主要进行表头的输出。
图2流程图三、系统的设计与实现(一)main()输出1.输出二叉树操作2.进行输出二叉树操作3.退出编译码操作系统,并让用户选择所进行的操作,对其调用。
该模块的具体代码如下所示:void main(){int i,n,s=1;hnodetype huffnode[maxnode];while(s){shuchu();scanf("%d",&i);switch(i){case 1:{haffmantree(huffnode,&n);break;}case 2:{haffmancode();break;}case 3:s=0;break;}}}分析:首先输出一个主菜单,方便用户进行操作,用switch语句调用函数使用户对其进行选择要执行的操作(1.输出二叉树操作,2.进行编译码操作,3.退出程序)。
(二)运算该模块的具体代码如下所示:1.权值运算quanzhi()分析:此函数用于对一串字符进行求权值运算,利用循环将一串字符中每个字符的个数设定为权值。
void quanzhi(int t[maxleaf],char s[maxleaf],int n)//求权值函数,将句子中的字符出现的个数当作权值{int i,j,h;for(i=0;i<n;i++){for(j=0;j<n;j++)if(s[i]==s[j])h++;t[i]=h;}}2.印二叉树函数huffmantree( )void haffmantree(hnodetype huffnode[maxnode],int *m){int i,j,n,k;int m1,m2,x1,x2;char s[maxleaf],t[maxleaf];printf("输入叶子结点个数:");scanf("%d",&n);for(i=0;i<2*n-1;i++)//数组huffnode[]初始化{huffnode[i].weight=0;huffnode[i].parent=-1;huffnode[i].lchild=-1;huffnode[i].rchild=-1;}printf("输入要编译的句子的\n");for(i=0;i<n;i++){printf("第%d个结点",i+1);scanf("%d",&huffnode[i].weight);getchar();}printf("印二叉树:\n");for(i=0;i<n;i++){quanzhi(t,s,n);k=huffnode[i].weight;}for(i=0;i<n-1;i++){//构造哈夫曼树m1=m2=maxvalue;x1=x2=0;for(j=0;j<n+i;j++){//选取最小和次小两个权值if(huffnode[j].parent==-1&&huffnode[j].weight<m1){m2=m1;x2=x1;m1=huffnode[j].weight;x1=j;}elseif(huffnode[j].parent==-1&&huffnode[j].weight<m2){m2=huffnode[j].weight;x2=j;}}//将找出的两棵子树合并为一颗子树huffnode[x1].parent=n+i;huffnode[x2].parent=n+i;huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;huffnode[n+i].lchild=x1;huffnode[n+i].rchild=x2;}for(i=0;i<2*n-1;i++){printf(" %4d",k);printf(" %4d",huffnode[i].lchild);printf(" %4d",huffnode[i].rchild);printf(" %4d\n",huffnode[i].parent);}*m=n;}3.编译码运算huffmancode()void haffmancode(){hnodetype huffnode[maxnode];hcodetype huffcode[maxleaf],cd;int i,j,c,p,n=0;haffmantree(huffnode,&n);for(i=0;i<n;i++){cd.start=n-1;c=i;p=huffnode[c].parent;while(p!=-1){if(huffnode[p].lchild==c)cd.bit[cd.start]=0;elsecd.bit[cd.start]=1;cd.start--;c=p;p=huffnode[c].parent;}for(j=cd.start+1;j<n;j++)huffcode[i].bit[j]=cd.bit[j];huffcode[i].start=cd.start;}for(i=0;i<n;i++){printf("第%d个译码为:",i+1);for(j=huffcode[i].start+1;j<n;j++)printf("%4d",huffcode[i].bit[j]);printf("\n");}}4.输出运算 shuchu()void shuchu(){printf("********************************************************************************\n");printf("*** |** 哈夫曼树的编译码 ** | ***\n");printf("*** |** 1.输出二叉树操作 ** | ***\n");printf("*** |** 2.进行编译码操作 ** | ***\n");printf("*** |** 3.退出编译码操作系统** | ***\n");printf("********************************************************************************\n");printf("请选择要进行的操作:");}四、系统测试(一)测试主函数main()函数该测试主要进行对主函数调用以及输出的测试,测试的结果:(二)测试印二叉树函数测试选择1,选择1操作首先输入叶子节点数,然后输入要编译的句子,分别输入第n+1个节点,然后系统会将输入字符的个数当作权值进行编译输出二叉树,测试结果为:(三)测试译码运算函数测试选择2,输入要选择的操作2,然后按要求依次输入需要的值,系统会根据输入的数据进行译码操作,最后输出译码。
输出结果为:(四)测试退出函数测试选择3进行退出,测试结果为:五、总结系统功能:系统完成了将一段字符串进行哈夫曼加密,用户将自己的选择输入程序,然后按照程序的提示进行输入,系统将根据输入进行编码、译码操作,然后印出编译的二叉树,以及每个字符的译码。
不足:系统没有将印哈夫曼树操作完成,系统没有将字符的权值根据大小将左孩子设为最小权值,将次小权值设为右孩子,导致加密有许多种,哈夫曼树也创建了许多种,输出的译码不唯一。