哈夫曼编码资料
- 格式:doc
- 大小:100.22 KB
- 文档页数:24
哈夫曼编码的背景和意义摘要:1.哈夫曼编码的简介2.哈夫曼编码的背景3.哈夫曼编码的意义4.哈夫曼编码的应用场景5.如何在实际应用中使用哈夫曼编码6.哈夫曼编码的优势与局限性7.总结正文:**一、哈夫曼编码的简介**哈夫曼编码(Huffman Coding)是一种数据压缩编码方法,它可以将原始数据转换为更简洁的形式,从而减少存储空间和传输时的带宽需求。
通过哈夫曼编码,我们可以更有效地利用资源,提高数据处理效率。
**二、哈夫曼编码的背景**哈夫曼编码起源于20世纪50年代,由美国计算机科学家DavidA.Huffman发明。
在当时,计算机存储空间和传输速率非常有限,哈夫曼编码的出现为解决这一问题提供了新的思路。
经过多年的发展,哈夫曼编码已成为现代数据压缩领域的核心技术之一。
**三、哈夫曼编码的意义**1.降低存储和传输成本:通过压缩数据,哈夫曼编码能有效减少存储空间和传输带宽的需求,降低成本。
2.提高数据处理效率:哈夫曼编码可以将冗余信息去除,使数据更加简洁,便于后续处理。
3.促进通信技术发展:在无线通信等领域,带宽资源有限,哈夫曼编码有助于提高通信速率,推动技术进步。
**四、哈夫曼编码的应用场景**1.文件压缩:如ZIP、RAR等压缩格式均采用了哈夫曼编码。
2.图像压缩:JPEG、PNG等图像格式使用了哈夫曼编码或其他类似方法进行压缩。
3.通信协议:许多通信协议,如HTTP、FTP等,都采用了哈夫曼编码进行数据压缩。
**五、如何在实际应用中使用哈夫曼编码**1.确定编码字符:首先,确定需要编码的字符集,例如英文字母、数字等。
2.统计字符出现频率:对字符集进行统计,了解各个字符出现的频率。
3.构建哈夫曼树:根据字符出现频率,构建哈夫曼树。
哈夫曼树是一种二叉树,用于表示字符及其对应的编码。
4.生成编码表:根据哈夫曼树,为每个字符分配一个编码。
编码表记录了字符与其对应的编码关系。
5.编码和解码:在实际应用中,根据编码表对数据进行编码和解码。
c语言哈夫曼树的构造及编码一、哈夫曼树概述哈夫曼树是一种特殊的二叉树,它的构建基于贪心算法。
它的主要应用是在数据压缩和编码中,可以将频率高的字符用较短的编码表示,从而减小数据存储和传输时所需的空间和时间。
二、哈夫曼树的构造1. 哈夫曼树的定义哈夫曼树是一棵带权路径长度最短的二叉树。
带权路径长度是指所有叶子节点到根节点之间路径长度与其权值乘积之和。
2. 构造步骤(1) 将待编码字符按照出现频率从小到大排序。
(2) 取出两个权值最小的节点作为左右子节点,构建一棵新的二叉树。
(3) 将新构建的二叉树加入到原来排序后队列中。
(4) 重复上述步骤,直到队列只剩下一个节点,该节点即为哈夫曼树的根节点。
3. C语言代码实现以下代码实现了一个简单版哈夫曼树构造函数:```ctypedef struct TreeNode {int weight; // 权重值struct TreeNode *leftChild; // 左子节点指针struct TreeNode *rightChild; // 右子节点指针} TreeNode;// 构造哈夫曼树函数TreeNode* createHuffmanTree(int* weights, int n) {// 根据权值数组构建节点队列,每个节点都是一棵单独的二叉树TreeNode** nodes = (TreeNode**)malloc(sizeof(TreeNode*) * n);for (int i = 0; i < n; i++) {nodes[i] = (TreeNode*)malloc(sizeof(TreeNode));nodes[i]->weight = weights[i];nodes[i]->leftChild = NULL;nodes[i]->rightChild = NULL;}// 构建哈夫曼树while (n > 1) {int minIndex1 = -1, minIndex2 = -1;for (int i = 0; i < n; i++) {if (nodes[i] != NULL) {if (minIndex1 == -1 || nodes[i]->weight < nodes[minIndex1]->weight) {minIndex2 = minIndex1;minIndex1 = i;} else if (minIndex2 == -1 || nodes[i]->weight < nodes[minIndex2]->weight) {minIndex2 = i;}}}TreeNode* newNode =(TreeNode*)malloc(sizeof(TreeNode));newNode->weight = nodes[minIndex1]->weight + nodes[minIndex2]->weight;newNode->leftChild = nodes[minIndex1];newNode->rightChild = nodes[minIndex2];// 将新构建的二叉树加入到原来排序后队列中nodes[minIndex1] = newNode;nodes[minIndex2] = NULL;n--;}return nodes[minIndex1];}```三、哈夫曼编码1. 哈夫曼编码的定义哈夫曼编码是一种前缀编码方式,它将每个字符的编码表示为二进制串。
数据结构哈夫曼编码【标题】数据结构:深入探索哈夫曼编码的奥秘【引言】数据结构是计算机科学中重要的基础知识,而哈夫曼编码作为一种经典的数据压缩算法更是备受推崇。
本文将深入探索哈夫曼编码的原理与应用,帮助读者全面理解该数据结构的大局及其潜在的威力。
通过从简到繁、由浅入深的方式,本文将层层拆解哈夫曼编码,从而带领读者揭示其背后的奥秘。
【正文】一、哈夫曼编码的概念及基本原理1. 哈夫曼编码的定义哈夫曼编码是一种变长编码方式,将出现频率较高的字符赋予较短的编码,从而实现数据压缩的目的。
其核心思想是根据字符出现频率构建一颗哈夫曼树,对于每个字符的编码规则,以其所在路径的0和1来表示。
2. 哈夫曼编码的构建过程(1)统计字符出现频率,构建字符频率表。
(2)使用字符频率表构建哈夫曼树。
(3)递归遍历哈夫曼树,生成每个字符的编码规则表。
二、哈夫曼编码的应用1. 数据压缩哈夫曼编码的最大优势在于可以有效地减少数据的存储空间,实现数据的压缩。
通过将高频字符赋予短编码,低频字符赋予长编码,哈夫曼编码可以最大程度地降低数据的存储需求。
2. 传输效率提升在数据传输过程中,哈夫曼编码可以减少数据的传输量,提高传输效率。
尤其是在网络传输中,由于带宽的限制,通过使用哈夫曼编码可以显著减少数据传输的时间和资源消耗。
3. 数据加密哈夫曼编码也可以作为一种简单的数据加密手段。
通过将字符的真实含义隐藏在编码中,哈夫曼编码为数据加密提供了一种简单而高效的方法。
三、哈夫曼编码的实际案例1. 文本文件压缩将文本文件进行哈夫曼编码压缩后,可以有效地减少存储空间的占用,提高文件的传输效率。
2. 图像文件压缩在图像文件中,像素的出现频率决定了其在哈夫曼编码中的编码长度。
对于像素出现频率较高的区域,通过哈夫曼编码可以显著减少存储空间,保持图像质量的同时提高传输效率。
3. 音频文件压缩哈夫曼编码在音频文件的压缩中也有广泛应用。
通过合理地构建哈夫曼编码表,可以实现对音频文件的高效压缩和传输。
(完整)哈夫曼编码_汉明编码编辑整理:尊敬的读者朋友们:这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)哈夫曼编码_汉明编码)的内容能够给您的工作和学习带来便利。
同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。
本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)哈夫曼编码_汉明编码的全部内容。
1 课题描述信息论理论基础的建立,一般来说开始与香农(C.E。
Shannon)在研究通信系统时所发表的论文。
信息论是在信息可以度量的基础上,对如何有效、可靠的传递信息进行研究的科学,它涉及信息亮度、信息特性、信息传输速率、信道容量、干扰对信息传输的影响等方面的知识。
通常把上述范围的信息论称为狭义信息论,又因为它的创始人是香农,故又称为香农信息论。
广义信息论则包含通信的全部统计问题的研究,除了香农信息论之外,还包括信号设计、噪声理论、信号的检测与估值等。
当信息在传输、存储和处理的过程中,不可避免的要受到噪声或其他无用信号的干扰时,信息理论会为可靠、有效的从数据中提取信息提供必要的根据和方法。
因此必须研究噪声和干扰的性质以及它们与信息本质上的差别,噪声与干扰往往具有某种统计规律的随机特性,信息则具有一定的概率特性,如度量信息量的熵值就是概率性质的。
信息论、概率轮、随机过程和数理统计学是信息论应用的基础和工具。
信息论主要研究如何提高信息系统的可靠性、有效性、保密性和认证性,以使信息系统最优化.所谓可靠性高就是要使信源发出的消息经过信道传输以后,尽可能准确的、不失真的再现在接收端;而所谓有效性高,就是经济效果好,即用尽可能少的资源和尽可能少的设备来传送一定数量的信息;所谓保密性就是隐蔽和保护通信系统中传送的信息,使它只能被授权接受者获取,而不能被未授权者接受和理解;而认证性是指接受者能正确的判断所接受的消息的正确性,验证消息的完整性,而不是接收伪造的和被修改的信息。
1、 哈夫曼编码哈夫曼编码是一种编码方式,是可变编码的一种,该方法完全依据字符出现的概率来构造字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做的是Huffman 编码。
哈夫曼编码一般是以哈夫曼树为例,即最优二叉树,带全路径最小的二叉树,经常用于数据压缩,即数据的无损耗压缩。
这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
哈夫曼编码的平均码长定义为:()()()Tc CB T f c dc ∈=∑,使平均码长达到最小的前缀码编码方案称为给定编码字符集C 的最优前缀码。
哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T 。
试验程序如下:#include<iostream>#include<string> using namespace std; const int n=6;const int m=2*n-1; class tree {public: int lch,rch,pe; float weight; string s,s3;void creat_Huffmantree();//建立huffman 树 void bianma_Huffmantree();//huffman 编码 void yima_Huffmantree();//huffman 译码 };tree hftree[m+1];void tree::creat_Huffmantree() { int i,j,s1,s2,p1,p2; for(i=1;i<=m;i++) { hftree[i].weight=0; hftree[i].lch=0; hftree[i].rch=0; hftree[i].pe=0; } cout<<"请输入每个节点的权重:"; for(i=1;i<=n;i++)cin>>hftree[i].weight; for(i=n+1;i<=m;i++) { s1=s2=10000;//最小权值 p1=p2=0;//最小权值的点 for(j=1;j<=i-1;j++) if(hftree[j].pe==0) if(hftree[j].weight<s1) { s2=s1; s1=hftree[j].weight; p2=p1; p1=j; } else if(hftree[j].weight<s2) { s2=hftree[j].weight; p2=j; } hftree[p2].pe=i;hftree[p1].pe=i;hftree[i].lch=p1;hftree[i].rch=p2;hftree[i].weight=hftree[p1].weight+hftree[p2].we ight;} }void tree::bianma_Huffmantree(){int i,k,j,k1,k2;for(i=1;i<=n;i++){ j=i;while(hftree[j].pe!=0){k=hftree[j].pe;if(hftree[k].lch==j)hftree[i].s3+='0';else hftree[i].s3+='1';j=k;}k1=hftree[i].s3.length();for(k2=k1-1;k2>=0;k2--)hftree[i].s+=hftree[i].s3[k2];}for(i=1;i<=n;i++)cout<<hftree[i].weight<<":"<<hftree[i].s<<endl; }void tree::yima_Huffmantree(){char c[1000];int k,k1;k=m;cout<<"请输入任何一个01串:";cin>>c;k1=strlen(c);for(int i=0;i<k1;i++){if(c[i]=='0')k=hftree[k].lch;else k=hftree[k].rch;if(hftree[k].lch==0){cout<<hftree[k].weight<<" ";k=m;}}cout<<endl;}int main() {tree t;t.creat_Huffmantree();t.bianma_Huffmantree();t.yima_Huffmantree(); }从得到的实验数据分析,先用给出的权重构造一颗树,分别写出其编码,然后随便输入一串01字符串,然后根据上面输入的编码,翻译出其译码即可。
哈夫曼编码是一种常用的无损数据压缩算法,通过利用字符出现的频率来构建可变长度的编码表,以实现高效的数据压缩。
本文将以C语言为例,介绍如何使用哈夫曼编码方法求出编码和平均码长。
1. 哈夫曼编码原理哈夫曼编码是一种前缀编码(Prefix Codes),即任何字符的编码都不是其他字符编码的前缀。
这种编码方式可以保证编码的唯一性,不会出现歧义。
哈夫曼编码的原理是通过构建哈夫曼树来实现对字符的编码,具体步骤如下:1)统计字符出现的频率,并根据频率构建最小堆或优先队列。
2)从频率最低的两个字符中选择一个根节点,频率之和作为其父节点的频率,将父节点重新插入到最小堆或优先队列中。
3)重复以上步骤,直到最小堆或优先队列中只剩下一个节点,即哈夫曼树的根节点。
4)根据哈夫曼树,得到字符的编码。
从根节点开始,左子树标记为0,右子树标记为1,沿途记录路径上的编码即可。
2. C语言实现哈夫曼编码以下是使用C语言实现哈夫曼编码的伪代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>// 定义哈夫曼树节点typedef struct Node {char data; // 字符数据int freq; // 字符频率struct Node* left;struct Node* right;} Node;// 创建哈夫曼树节点Node* createNode(char data, int freq) {Node* node = (Node*)malloc(sizeof(Node)); node->data = data;node->freq = freq;node->left = NULL;node->right = NULL;return node;}// 构建哈夫曼树Node* buildHuffmanTree(char* data, int* freq, int size) {// 构建最小堆或优先队列// 构建哈夫曼树}// 生成字符编码void generateHuffmanCode(Node* root, char* code, int depth) { // 生成编码}// 输出字符编码void printHuffmanCode(Node* root) {// 输出编码}// 计算平均码长double calculateAvgCodeLength(Node* root, int depth) {// 计算平均码长}int main() {char data[] = {'a', 'b', 'c', 'd', 'e', 'f'};int freq[] = {5, 9, 12, 13, 16, 45};int size = sizeof(data) / sizeof(data[0]);Node* root = buildHuffmanTree(data, freq, size);char code[100];generateHuffmanCode(root, code, 0);printHuffmanCode(root);double avgCodeLength = calculateAvgCodeLength(root, 0);return 0;}```以上伪代码实现了使用C语言构建哈夫曼树、生成字符编码和计算平均码长的过程。
哈夫曼编码译码系统一、需求分析1、程序的基本功能:①构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权值,建立哈夫曼树;利用已将建好的哈弗曼树求每个叶结点的哈夫曼编码,并保存。
②编码:利用已构造的哈弗曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。
③译码:将“密文”文件中的0、1代码序列进行译码。
④打印“密文”文件:将文件以紧凑格式显示在终端上,同时,将此字符形式的编码保存。
⑤打印哈夫曼树:将已在内存中的哈夫曼以凹入表形式显示在终端上。
2、输入输出要求:①从键盘接收字符集大小n、以及n个字符和n个权值;②构造哈夫曼树:将HFMTree数组中的各个位置的各个域都添上相关的值,并将结构体数组存入文件HTree.txt中。
③打印哈夫曼树:从HFMTree数组读取相关的结点信息,以凹入表方式将各个结点画出来;④构造哈夫曼编码:先从文件HTree.txt中读入相关的字符信息进行哈夫曼编码,将字符与其对应的编码存入文件HNode.txt中;⑤编码:利用已构造的哈夫曼树对文件进行编码,打印结果,并将结果存入新建文件中;⑥译码:将密文文件中的内容利用HNode.txt中建立的编码规则进行翻译,打印结果,并将结果存入新建文件中。
3、测试数据:输入叶子结点个数为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。
二、概要设计1、抽象数据类型的定义:①采用静态链表作为哈夫曼树的存储结构;②求哈夫曼编码时使用一维数组HCode作为哈夫曼编码信息的存储。
2、主模块的流程及各子模块的主要功能:①int main(){主菜单;swich语句结构选择;return 0;}②in_park(){输入车牌号;若停车场已满,停入便道中,否则停入停车场;}③output(){输入所要离开车辆的车牌号,以及离开时间;停在便道内的第一辆车进入停车场;}③show_car(){依次显示停车场内的车辆信息;}show_queue(){依次显示便道内的车辆信息;}3、模块之间的层次关系:主函数Creat output show_car show_queuejudge三、详细设计1、定义的相关数据类型:①哈夫曼树结点:typedef struct{int weight;int park;int lchild;int rchild;char ch;}②哈弗曼编码结点:typedef struct{Car Park[MAX_PARK];int top;}ParkStack;2、函数的调用关系:mainin_park output show_car show_queuejudge四、调试分析调试中遇到的问题及对问题的解决方法:⑴遇到的问题:①编码时最后一位总是多出一位数字;②编码时出现无限循环;⑵解决方法:①改变构造哈夫曼树时的循环条件;②改变构造哈夫曼编码的循环条件;五、使用说明及测试结果1、使用说明:①进入主菜单,选择所要进行的操作;②构造哈夫曼树:输入叶结点个数,及其字符与权值;③选择显示哈夫曼树,哈夫曼树以凹入表形式显示;④选择构造哈夫曼编码,即构造哈夫曼编码,若成功,则显示成功;⑤选择编码:选择进行键盘输入或者从文件中获取。
2、测试结果:停车场容量为5,连续有7辆车到来,牌照号分别为f001、f002、f003、f004、f005、f006、f007,前5辆车进入停车场1-5号车位,第6、7辆车停入便道的1、2号位置上。
牌照号为f003的车辆从停车场开走后,f006从便道进入停车场,便道上只剩f007。
六、伪码算法#include<conio.h>#include<stdio.h>#include<string.h>#include<iostream.h>#include<fstream.h>#include <iomanip.h>#include "stdlib.h"#define N 4#define MAXVSLUE 1000typedef struct{char letter;int weight;int parent;int lchild;int rchild;}HNodeType;HNodeType HNode[2*N-1];#define MAXBIT 10typedef struct{char bit[MAXBIT];int start;}HCodeType;HCodeType HCode[N];void Creat_HuffMtree(HNodeType HFMTree[],int n) ; /* 构造哈夫曼树*/void HaffmanConde(HNodeType HFMTree[], HCodeType HuffCode[]);void Display();void makecode1(char s[MAXVSLUE]);void makecode2(char s[MAXVSLUE]);void yicode1();void yicode2();void Dis1();void Dis2();void printing(int root,int length);void main(){cout<<"*****************************欢迎进入编译器系统********************************"<<endl;Display();for(;;){char ch;char c=getch();if(c=='4')break;switch(c){case '1':Dis2();ch=getch();switch(ch){case '1':Creat_HuffMtree(HNode,N) ;HaffmanConde(HNode,HCode);break;case '2':cout<<"此哈夫曼树的凹入法表示为"<<endl;printing(2*N-2,0);break;}Display();break;case '2':Dis1();ch=getch();char s[MAXVSLUE];switch(ch){case '1':makecode1(s);break;case '2':makecode2(s);break;}Display();break;case '3':Dis1();ch=getch();switch(ch){case '1':yicode1();break;case '2':yicode2();break;}Display();break;}}}void Creat_HuffMtree(HNodeType HFMTree[],int n) /* 构造哈夫曼树*/{/*构造的哈夫曼树存储于HFMTree[], n为叶子结点的个数*/int m1,x1,m2,x2; /* x1和x2存储最小和次小权值,m1和m2存储其位置*/int i,j;for(i=0;i<2*n-1;i++) /* HFMTree初始化*/{HFMTree[i].weight=0;HFMTree[i].parent=-1;HFMTree[i].lchild=-1;HFMTree[i].rchild=-1;}for(i=0;i<N;i++)HFMTree[i].letter=NULL;cout<<"依次输入"<<n<<"个叶子结点的符号和权值"<<endl; for(i=0;i<n;i++){cout<<"输入"<<i+1<<"个叶子符号";cin>>HFMTree[i].letter;cout<<"输入"<<i+1<<"个叶子权值";cin>>HFMTree[i].weight;} /* 出入n个叶子结点的权值,设为整型*/for(i=0;i<n-1;i++) /*构造哈夫曼树*/{x1=x2=MAXVSLUE;m1=m2=0;for(j=0;j<n+i;j++){if(HFMTree[j].parent==-1 && HFMTree[j].weight<x1){/*找出根结点具有最小和此最小权值的两棵树*/x2=x1;m2=m1;x1=HFMTree[j].weight;m1=j;}else if(HFMTree[j].parent==-1 && HFMTree[j].weight<x2){x2=HFMTree[j].weight;m2=j;}}/*将找出的两棵子树合并成一棵树*/HFMTree[m1].parent=n+i;HFMTree[m2].parent=n+i;HFMTree[n+i].weight=HFMTree[m1].weight+HFMTree[m2].weight;HFMTree[n+i].letter='z'-i;HFMTree[n+i].lchild=m1;HFMTree[n+i].rchild=m2;HFMTree[n+i].parent=-1;}FILE *fptr;if((fptr=fopen("HTree.txt","w"))!=NULL){fprintf(fptr, " letter weigth lchild rchildparent\n");for(i=0;i<2*N-1;i++ )fprintf(fptr, "%d %c %d %d%d %d\n" ,i,HFMTree[i].letter,HFMTree[i].weight, HFMTree [i].lchild,HFMTree[i].rchild,HFMTree[i].parent );}elseprintf("文件打开失败");fclose(fptr);printf(" letter weigth lchild rchild parent\n"); for(i=0;i<2*N-1;i++ )printf("%d %c %d %d %d%d\n" ,i,HFMTree[i].letter,HFMTree[i].weight, HFMTree[i].lchild,HFMTree[i].rchild,HFMTree[i].parent );}void HaffmanConde(HNodeType HFMTree[], HCodeType HUffCode[]) {FILE *fptr1,*fptr2;fptr1=fopen("HTree.txt","a");if(fptr1==NULL)printf("文件打开失败");HCodeType cd;int i,j,c,p;for(i=0;i<N;i++){cd.start=MAXBIT-1;c=i;fscanf(fptr1 ," %d%d%d%d",&HFMTree[i].weight,&HFMTree[i].lchild,&HFMTree[i].rchild,&HFMTree[i].parent );p=HFMTree[c].parent;while(p!=-1){if(HFMTree[p].lchild==c)cd.bit[cd.start]=0;else cd.bit[cd.start]=1;cd.start--;c=p;p=HFMTree[c].parent;}for(j=cd.start+1;j<MAXBIT;j++)HUffCode[i].bit[j]=cd.bit[j];HUffCode[i].start=cd.start+1;}fclose(fptr1);printf("字符权值代码\n");if((fptr2=fopen("HNode.txt","w"))!=NULL){for(i=0;i<N;i++){fprintf(fptr2,"%c ",HFMTree[i].letter);printf("%c ",HFMTree[i].letter);printf("%d ",HFMTree[i].weight);for(j=HUffCode[i].start;j<MAXBIT;j++)fprintf(fptr2,"%d",HUffCode[i].bit[j]);for(j=HUffCode[i].start;j<MAXBIT;j++)printf("%d",HUffCode[i].bit[j]);printf("\n");fprintf(fptr2,"\n");}}elseprintf("文件打开失败");fclose(fptr2);}void makecode1(char s[MAXVSLUE]){FILE *ptr;int i,m;char file[20];printf("\n输入要编码的文件名 \n");cin>>file;ptr=fopen(file,"r");if(ptr==NULL)printf("文件打开失败");for(i=0;i<MAXVSLUE;i++)s[i]=NULL;fgets(s,MAXVSLUE,ptr);int n,j;printf("输入保存密文的文件名");cin>>file;ptr=fopen(file,"w");n=strlen(s);for(i=0;i<n;i++){for(j=0;j<N;j++)if(s[i]==HNode[j].letter)break;for(m=HCode[j].start;m<MAXBIT;m++){fprintf(ptr,"%d",HCode[j].bit[m]);printf("%d",HCode[j].bit[m]);}}fclose(ptr);printf("\n");}void makecode2(char s[MAXVSLUE]){char file[100];FILE *ptr;int n,i,j,m;printf("输入要编码的字符串:");scanf("%s",s);n=strlen(s);for(i=0;i<n;i++){for(j=0;j<N;j++)if(s[i]==HNode[j].letter)break;for(m=HCode[j].start;m<MAXBIT;m++)printf("%d",HCode[j].bit[m]);}printf("\n输入保存密文的文件名"); cin>>file;ptr=fopen(file,"w");n=strlen(s);for(i=0;i<n;i++){for(j=0;j<N;j++)if(s[i]==HNode[j].letter)break;for(m=HCode[j].start;m<MAXBIT;m++){fprintf(ptr,"%d",HCode[j].bit[m]);}}fclose(ptr);printf("\n");printf("\n");}void yicode1(){int i,c=2*N-2;char s[MAXVSLUE];char file[100];for(i=0;i<MAXVSLUE;i++)s[i]=NULL;char ch[2]={0};FILE *ptr;printf("输入要译码的文件名");cin>>file;ptr=fopen(file,"r");if(ptr==NULL)printf("文件打开失败");ch[0]=fgetc(ptr);while(ch[0]!=EOF){strcat(s,ch);ch[0]=fgetc(ptr);}fclose(ptr);printf("输入保存译文的文件名");cin>>file;ptr=fopen(file,"w");if(ptr==NULL)printf("文件打开失败");i=0;while(s[i]!=NULL){if(s[i]=='0'){c=HNode[c].lchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){printf("%c",HNode[c].letter);fprintf(ptr,"%c",HNode[c].letter);c=2*N-2;}}else if(s[i]=='1'){c=HNode[c].rchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){printf("%c",HNode[c].letter);fprintf(ptr,"%c",HNode[c].letter);c=2*N-2;}}i++;}printf("译码成功, 密文在%s文件中\n",file);fclose(ptr);}void yicode2(){char file[100];FILE *ptr;int i,c=2*N-2;char s[MAXVSLUE];for(i=0;i<MAXVSLUE;i++)s[i]=NULL;printf("输入密文");scanf("%s",s);i=0;while(s[i]!=NULL){if(s[i]=='0'){c=HNode[c].lchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){printf("%c",HNode[c].letter);c=2*N-2;}}else if(s[i]=='1'){c=HNode[c].rchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){printf("%c",HNode[c].letter);c=2*N-2;}}i++;}printf("译码成功\n");printf("输入保存译文的文件名");cin>>file;ptr=fopen(file,"w");if(ptr==NULL)printf("文件打开失败");i=0;while(s[i]!=NULL){if(s[i]=='0'){c=HNode[c].lchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){fprintf(ptr,"%c",HNode[c].letter);c=2*N-2;}}else if(s[i]=='1'){c=HNode[c].rchild;if(HNode[c].lchild==-1 && HNode[c].rchild==-1){fprintf(ptr,"%c",HNode[c].letter);c=2*N-2;}}i++;}fclose(ptr);}void printing(int root,int length){int i;cout<<HNode[root].letter<<" ";for(i=0;i<length;i++)cout<<" ";for(i=length;i<25;i++)cout<<"*";cout<<endl;if(HNode[root].lchild!=-1){length+=2;printing(HNode[root].lchild,length);printing(HNode[root].rchild,length); }}void Display(){cout<<"1.系统初始化"<<endl;cout<<"2.编码"<<endl;cout<<"3.译码"<<endl;cout<<"4.退出"<<endl;}void Dis1(){cout<<"1.从文件读入"<<endl;cout<<"2.键盘输入"<<endl;}void Dis2(){cout<<"1.建立哈夫曼树构造哈夫曼编码"<<endl;cout<<"2.凹入法打印哈夫曼树"<<endl;}。