哈夫曼编译码的设计与实现实验报告

合集下载

《哈夫曼编码》实验报告

《哈夫曼编码》实验报告

《哈夫曼编码》实验报告《哈夫曼编码》实验报告一、实验目的1、掌握哈夫曼编码原理;2、熟练掌握哈夫曼树的生成方法;3、理解数据编码压缩和译码输出编码的实现。

二、实验要求实现哈夫曼编码和译码的生成算法。

三、实验步骤编写代码如下:#include#include#include#define MAXLEN 100typedef struct{int weight;int lchild;int rchild;int parent;char key;}htnode;typedef htnode hfmt[MAXLEN];int n;void inithfmt(hfmt t){int i;printf("\n");printf("--------------------------------------------------------\n"); printf("**********************输入区**********************\n");printf("\n请输入n=");scanf("%d",&n);getchar();for(i=0;i<2*n-1;i++){t[i].weight=0;t[i].lchild=-1;t[i].rchild=-1;t[i].parent=-1;}printf("\n");}void inputweight(hfmt t){int w;int i;char k;for(i=0;i<n;i++)< bdsfid="112" p=""></n;i++)<>{printf("请输入第%d个字符:",i+1);scanf("%c",&k);getchar();t[i].key=k;printf("请输入第%d个字符的权值:",i+1);scanf("%d",&w);getchar();t[i].weight=w;printf("\n");}}void selectmin(hfmt t,int i,int *p1,int *p2){long min1=999999;long min2=999999;int j;for(j=0;j<=i;j++)if(t[j].parent==-1)if(min1>t[j].weight){min1=t[j].weight;*p1=j;}for(j=0;j<=i;j++)if(t[j].parent==-1)if(min2>t[j].weight && j!=(*p1))//注意 j!=(*p1)) { min2=t[j].weight;*p2=j;}}void creathfmt(hfmt t){int i,p1,p2;inithfmt(t);inputweight(t);for(i=n;i<2*n-1;i++){selectmin(t,i-1,&p1,&p2);t[p1].parent=i;t[p2].parent=i;t[i].lchild=p1;t[i].rchild=p2;t[i].weight=t[p1].weight+t[p2].weight;}}void printhfmt(hfmt t){int i;printf("------------------------------------------------------------------\n");printf("**************哈夫曼编数结构:*********************\n"); printf("\t\t权重\t父母\t左孩子\t右孩子\t字符\t");for(i=0;i<2*n-1;i++){printf("\n");printf("\t\t%d\t%d\t%d\t%d\t%c",t[i].weight,t[i].parent,t[i].lc hild,t [i].rchild,t[i].key);}printf("\n------------------------------------------------------------------\n");printf("\n\n");}void hfmtpath(hfmt t,int i,int j){int a,b;a=i;b=j=t[i].parent;if(t[j].parent!=-1){i=j;hfmtpath(t,i,j);}if(t[b].lchild==a)printf("0");elseprintf("1");}void phfmnode(hfmt t){int i,j,a;printf("\n---------------------------------------------\n"); printf("******************哈夫曼编码**********************"); for(i=0;i<n;i++)< bdsfid="190" p=""></n;i++)<>{j=0;printf("\n");printf("\t\t%c\t",t[i].key,t[i].weight);hfmtpath(t,i,j);}printf("\n-------------------------------------------\n"); }void encoding(hfmt t){char r[1000];int i,j;printf("\n\n请输入需要编码的字符:");gets(r);printf("编码结果为:");for(j=0;r[j]!='\0';j++)for(i=0;i<n;i++)< bdsfid="207" p=""></n;i++)<>if(r[j]==t[i].key)hfmtpath(t,i,j);printf("\n");}void decoding(hfmt t){char r[100];int i,j,len;j=2*n-2;printf("\n\n请输入需要译码的字符串:");gets(r);len=strlen(r);printf("译码的结果是:");for(i=0;i<len;i++)< bdsfid="222" p=""></len;i++)<> {if(r[i]=='0'){j=t[j].lchild;if(t[j].lchild==-1){printf("%c",t[j].key);j=2*n-2;}}else if(r[i]=='1'){j=t[j].rchild;if(t[j].rchild==-1){printf("%c",t[j].key);j=2*n-2;}}printf("\n\n");}int main(){int i,j;hfmt ht;char flag;printf("\n----------------------------------------------\n");printf("*******************编码&&译码&&退出***************");printf("\n【1】编码\t【2】\t译码\t【0】退出");printf("\n您的选择:");flag=getchar();getchar();while(flag!='0'){if(flag=='1')encoding(ht);else if(flag=='2')decoding(ht);elseprintf("您的输入有误,请重新输入。

哈弗曼编译器实验报告

哈弗曼编译器实验报告

实习报告题目:哈弗曼编译码器班级:电信系通信工程0902班完成日期:2010.11一、需求分析1、编写哈弗曼编译码器,其主要功能有(1)I:初始化(Initialization)。

从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树。

(2)E:编码(Encoding)。

利用已建好的哈夫曼树),对从终端输入的正文进行编码,然后从终端输出。

(3)D:译码(Decoding )。

利用已建好的哈夫曼树将从终端输入的代码进行译码,结果从终端输出。

(4)P:印哈夫曼树(Print)。

将已编码的的哈夫曼树显示在终端上,同时将此字符形式的哈夫曼树。

2、测试数据:输入的字符={a, b, c, d, e}其对应的权值={5,29,7,8,14}二、概要设计1、二哈弗曼树的抽象数据类型定义为:ADT HuffmanTree{数据对象D:D是具有相同性质的数据元素的集合数据关系R:若D=Φ,则R= Φ,哈弗曼树为空若D≠Φ,则R= {H},H是如下二元关系:(1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱(2)若D-{root}≠Φ,则存在D-{root}={Dl,Dr}。

且Dl∩Dr=Φ(3)若Dl≠Φ,则Dl中存在唯一的数据元素Xl,<root, Xl>属于H,且存在Dl上的关系H1属于H。

若Dr≠Φ,则Dr中存在唯一的数据元素Xr,<root, X>属于H,且存在Dr上的关系Hr属于HH={<root, Xl>,<root, X>,Hl,Hr};(4)(Dl,{Hl})是一棵符合本定义的哈弗曼树,称为根的左子树。

(Dr,{Hr})是一棵符合本定义的哈弗曼树,称为根的右子树。

基本操作:HuffmanCoding(&HT, &HC, &sum)操作结果:建立哈弗曼树并进行编码将编码存放在HC中,并返回字符的个数。

Encoding(HT, HC, sum)操作结果:利用已建立的哈弗曼树对字符进行编码Decoding(HuffmanTree HT,HuffmanCode HC,int sum)操作结果:对输入的密码进行翻译Print(HT, HC, sum)操作结果:打印建立好的哈弗曼树}ADT HuffmanTree三、详细设计(1)哈弗曼树每个节点的定义:typedef struct{unsigned int weight;unsigned int parent,lchild,rchild;char elemt[20];}HTNode,*HuffmanTree;(2)定义指向哈弗曼树的指针,用于动态分配空间typedef char **HuffmanCode;(3)哈弗曼树的基本操作Void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){ //建立哈弗曼树,求出哈弗曼编码if (n<=1)return;m=2*n-1; //n 个叶子的HuffmanTree共有2n-1个结点HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));for(p=HT+1,i=0; i<n; ++i,++p,++w)*p={*w,0,0,0};//给前n个单元初始化for(;i<=m; ++i,++p)*p ={0,0,0,0}; //从叶子之后的存储单元清零for(i=n+1;i<=m; ++i){ //建Huffman树(从n个叶子后开始存内结点) Select(HT, i-1, s1, s2);//选择parent为0且weight最小的两个结点,HT[s1].parent=i; HT[s2].parent=i; //给双亲分量赋值HT[i].lchild=s1; HT[i].rchild=s2; //给合并后的内结点赋孩子值HT[i].weight=HT[s1].weight+ HT[s2].weight;} //以上建立了哈弗曼树,以下求哈弗曼编码HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量(一维数组)cd=(char*) malloc(n*sizeof(char)); //分配求编码的临时最长空间cd[n-1]=“\0”; //编码结束符(从cd[0]~cd[n-1]为合法空间)for(i=1;i<=n;++i) //逐个字符求Huffman编码{start=n-1; //编码结束符位置for(c=i,f=HT[i].parent; f!=0; c=f, f=HT[f].parent)//从叶子到根逆向求编码if(HT[f].lchild==c) cd[--start]=“0”;else cd[--start]=“1”;HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间,并以数组形式存放各码串指针strcpy(HC[i],&cd[start]); //从cd复制编码串到HC所指空间}free(cd); //释放临时空间}//HuffmanCodingfor(i=0; i<n; ++i){start=n-1; //编码结束符位置for(c=i, f=HT[i].parent;f!=0;c=f, f=HT[f].parent) {If(HT[f].lchild==c) cd[--start]=“0”;else cd[--start]=“1”;} / /从叶子到根逆向求编码}// HuffmanCodingVoid Encoding(HuffmanTree HT,HuffmanCode HC,int sum) //利用已经建立的哈弗曼树对输入的字符进行哈弗曼编码{for(int i=0;a[i]!='\0';i++)//依次判断字符的对应的哈弗曼编码{for(int n=0;HT[n].elemt[0];n++)//查找a[i]在哈弗曼树中的位置{strcpy(p,HC[n]);p=p+strlen(HC[n]);break;//把编码复制接到code后}}i=0;printf("得到的编码是:\n");while(code[i]!='\0') //输出字符对应的哈弗曼编码{printf("%c",code[i++]);}}// EncodingVoid Decoding(HuffmanTree HT,HuffmanCode HC,int sum) //译码{while(code1[i]!='\0'){if(code1[i]=='0') b=HT[b].lchild;//当遇到0时指向哈弗曼树的左子树else if(code1[i]=='1') b=HT[b].rchild;//当遇到1时指向哈弗曼树的右子树}if(HT[b].lchild==0&&HT[b].rchild==0)//当左右子树均为空时表明已找到对应的字符{a1[n++]=HT[b].elemt[0];b=2*sum-2;//将对应的字符放在数组a1中并重新设置b的值继续翻译 }i++;}// DecodingVoid Print(HuffmanTree HT,HuffmanCode HC,int sum)//打印哈弗曼树{for(int i=0;i<2*sum-1;i++)//从首元素开始,逐个输入哈弗曼树的各项数据{printf("%d%c%d%d%d",i,HT[i].elemt[0],HT[i].parent,HT[i].lch ild,HT[i].rchild);}}// Print四、调试分析1、由于书上有详细的建立哈弗曼树的算法,编码,译码,打印哈弗曼树的算法比较简单,程序的模块比较简单,所以整体的思路比较清晰,但是在将算法,写为C语言的过程中,出现了很多的语法和逻辑上的错误,所以用了很多的时间调试,修改错误。

数据结构哈夫曼树编码及译码的实现实验报告

数据结构哈夫曼树编码及译码的实现实验报告

实验:哈夫曼树编码及译码的实现一.实验题目给定字符集的HUFFMANN编码与解码,这里的字符集及其字符频数自己定义,要求输出个字符集的哈夫曼编码及给定的字符串的哈夫曼码及译码结果。

二.实验原理首先规定构建哈夫曼树,然后进行哈夫曼树的编码,接着设计函数进行字符串的编码过程,最后进行哈夫曼编码的译码。

首先定义一个结构体,这个结构体定义时尽可能的大,用来存放左右的变量,再定义一个地址空间,用于存放数组,数组中每个元素为之前定义的结构体。

输入n个字符及其权值。

构建哈夫曼树:在上述存储结构上实现的哈夫曼算法可大致描述为:1.首先将地址空间初始化,将ht[0…n-1]中所有的结点里的指针都设置为空,并且将权值设置为0.2.输入:读入n个叶子的权值存于向量的前n个分量中。

它们是初始森林中n个孤立的根结点上的权值。

3.合并:对森林中的树共进行n-1次合并,所产生的新结点依次放入向量ht的第i个分量中。

每次合并分两步:①在当前森林ht[0…i-1]的所有结点中,选取权最小和次小的两个根结点[s1]和 [s2]作为合并对象,这里0≤s1,s2≤i-1。

②将根为ht[s1]和ht[s2]的两棵树作为左右子树合并为一棵新的树,新树的根是新结点ht[i]。

具体操作:将ht[s1]和ht[s2]的parent置为i,将ht[i]的lchild和rchild分别置为s1和s2 .新结点ht[i]的权值置为ht[s1]和ht[s2]的权值之和。

4.哈夫曼的编码:约定左子为0,右子为1,则可以从根结点到叶子结点的路径上的字符组成的字符串作为该叶子结点的编码。

当用户输入字母时。

就在已经找好编码的编码结构体中去查找该字母。

查到该字母就打印所存的哈夫曼编码。

接着就是完成用户输入0、1代码时把代码转成字母的功能。

这是从树的头结点向下查找,如果当前用户输入的0、1串中是0则就走向该结点的左子。

如果是1这就走向该结点的右结点,重复上面步骤。

哈夫曼编译码的设计与实现实验报告

哈夫曼编译码的设计与实现实验报告

哈夫曼编/译码的设计与实现实验报告问题描述利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。

对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

试为这样的信息收发编写一个哈夫曼码的编/译码系统。

基本要求(1)接收原始数据:从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree.dat中。

(2)编码:利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入),对文件中的正文进行编码,然后将结果存入文件codefile.dat中。

(3)译码:利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat中。

(4)打印编码规则:即字符与编码的一一对应关系。

运行与调试(1)利用教科书中的数据调试程序。

(2)用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS-PROGRAM-IS-MY-FA VORITE”。

字符 A B C D E F G H I J K L M 频度186 64 13 22 32 103 21 15 47 57 1 5 32 20 字符N O P Q R S T U V W X Y Z频度57 63 15 1 48 51 80 23 8 18 1 16 1实验小结通过这次实验,让我对于树的应用多了认识,在读取文件时,遇到的一些困难,不过在和同学交流的过程中,解决了这个问题,我觉的自己对于树及文件的应用又有了一些进步。

通过这次实验,感觉收获很大。

源程序// 哈夫曼编译码的设计与实现.cpp : 定义控制台应用程序的入口点。

//#include "stdafx.h"#include<iostream>#include<fstream>#include<string>#define Maxvalue 10000#define MAXBIT 200using namespace std;struct node{char letter;string num;};typedef struct{char letter;int weight; //结点权值int parent;int lchild;int rchild;}HnodeType;typedef struct{int bit[MAXBIT];int start;}HcodeType;HnodeType *HaffmanTree(int n){HnodeType *HuffNode;HuffNode=new HnodeType[2*n-1];int i,j;int m1,m2,x1,x2;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;}cout<<"请输入每个叶子结点的字母和权值(形如A5):"<<endl;for(i=0;i<n;i++)cin>>HuffNode[i].letter>>HuffNode[i].weight; //输入n个叶子结点的权值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;}else{if(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;}cout<<" weight"<<" lchild"<<" rchild"<<" parent"<<endl; for(i=0;i<2*n-1;i++)cout<<i<<"--"<<" "<<HuffNode[i].weight<<" "<<HuffNode[i].lchild<<" "<<HuffNode[i].rchild<<" "<<HuffNode[i].parent<<endl;ofstream outFile("hfmtree.dat",ios::out);if(!outFile)cerr<<"文件打开失败!"<<endl;else{outFile<<" weight"<<" lchild"<<" rchild"<<"parent"<<endl;for(i=0;i<2*n-1;i++)outFile<<i<<"--"<<" "<<HuffNode[i].weight<<""<<HuffNode[i].lchild<<" "<<HuffNode[i].rchild<<""<<HuffNode[i].parent<<endl;outFile.close();}return HuffNode;}void HaffmanCode(HnodeType *HuffNode,int n){HcodeType *HuffCode,cd;HuffCode=new HcodeType[2*n-1];int c,p,i,j;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++){cout<<HuffNode[i].letter;for(j=HuffCode[i].start+1;j<n;j++)cout<<HuffCode[i].bit[j];cout<<endl;}ofstream outFile1("codefile.dat",ios::out|ios::binary);if(!outFile1)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<n;i++){outFile1<<HuffNode[i].letter;for(j=HuffCode[i].start+1;j<n;j++)outFile1<<HuffCode[i].bit[j];outFile1<<endl;}outFile1.close();}}int _tmain(int argc, _TCHAR* argv[]){HnodeType *HuffNode;int n,i;cout<<"请输入叶子结点个数:";cin>>n;if(cin.fail()){cout<<"输入有误!"<<endl;return 0;}HuffNode=HaffmanTree(n);HaffmanCode(HuffNode,n);int num;cout<<"请输入要加密的字母串的长度(空格也要计算在内):";cin>>num;char *l1;char l;node l2[27];l1=new char[num];cout<<"请输入要加密的字母串(请用大写,如有空格请用“-”代替):";for(int n=0;n<num;n++)cin>>l1[n];ofstream outFile2("bianma.dat",ios::out|ios::binary);if(!outFile2)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<num;i++)outFile2<<l1[i];outFile2.close();}ifstream inFile1("codefile.dat",ios::in|ios::binary);ifstream inFile2("bianma.dat",ios::in|ios::binary);cerr<<"读取文件失败!"<<endl;if(!inFile2)cerr<<"读取文件失败!"<<endl;else{while(inFile2.peek ()!=EOF){inFile2>>l;for(i=0;i<2*n-1;i++){inFile1>>l2[i].letter;inFile1>>l2[i].num;}for(i=0;i<n;i++){if(l2[i].letter==l)cout<<l2[i].num<<" ";}}inFile1.close();inFile2.close();}delete []l1;cout<<endl;int a;cout<<"请输入要进行译码的串的个数:";cin>>a;string *s;s=new string[a];cout<<"请输入要解码的串(每输入一个串,请按一次【Enter】键):"<<endl; for(i=0;i<a;i++)cin>>s[i];ofstream outFile4("yima.dat",ios::out);if(!outFile4)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<a;i++)outFile4<<s[i]<<endl;outFile4.close();}ifstream inFile3("codefile.dat",ios::in|ios::binary);cerr<<"读取文件失败!"<<endl;else{for(i=0;i<2*n-1;i++){inFile3>>l2[i].letter;inFile3>>l2[i].num;}ifstream inFile4("yima.dat",ios::in);if(!inFile4)cerr<<"读取文件失败!"<<endl;else{for(int j=0;j<a;j++)inFile4>>s[j];}for(int j=0;j<a;j++){for(i=0;i<n;i++){if(l2[i].num==s[j])cout<<l2[i].letter;}}inFile3.close();}return 0;}。

哈夫曼编码译码系统实验报告,数据结构课程设计报告书

哈夫曼编码译码系统实验报告,数据结构课程设计报告书

专业资料安徽大学数据结构课程设计报告项目名称:哈弗曼编/译码系统的设计与实现姓名:鉏飞祥学号:E21414018专业:软件工程完成日期2016/7/4计算机科学与技术学院1 .需求分析1.1问题描述•问题描述:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。

对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

试为这样的信息收发站设计一个哈夫曼编译码系统。

1.2基本要求(1) 输入的形式和输入值的范围;(2) 输出的形式;(3) 程序所能达到的功能。

1.基本要求(1)初始化(Initialzation)。

从数据文件DataFile.data中读入字符及每个字符的权值,建立哈夫曼树HuffTree;(2)编码(EnCoding)。

用已建好的哈夫曼树,对文件ToBeTran.data中的文本进行编码形成报文,将报文写在文件Code.txt中;(3)译码(Decoding)。

利用已建好的哈夫曼树,对文件CodeFile.data 中的代码进行解码形成原文,结果存入文件Textfile.txt中;(4)输出(Output)。

输出DataFile.data中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.data及其报文Code.txt;输出CodeFile.data 及其原文Textfile.txt;2. 概要设计说明本程序中用到的所有抽象数据类型的定义。

主程序的流程以及各程序模块之间的层次(调用)关系。

(1)数据结构哈夫曼树的节点struct huff{int weight;int parent;int l;int r;};哈夫曼编码的存储struct huff *hufftree;(2)程序模块选择1到i-1中parent为0且权值最小的两个下标void Select(struct huff *HT, int n, int &s1, int &s2)构建哈夫曼树:void huffmancoding(struct huff *ht,int *w,int n)对原文进行编码:void code(char *c)根据报文找到原文:void decoding(char *zifu)3. 详细设计核心技术分析:1:构建哈夫曼树及生成哈夫曼编码:根据每个字符权值不同,根据最优二叉树的构建方法,递归生成哈夫曼树,并且用数组存放哈夫曼树。

哈夫曼树编码译码实验报告

哈夫曼树编码译码实验报告

数据结构课程设计设计题目:哈夫曼树编码译码课题名称院系学号姓名哈夫曼树编码译码年级专业成绩1、课题设计目的:在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,时常应用于数据压缩。

哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。

这张编码表的特殊之处在于,它是根据每一个源字符浮现的估算概率而建立起来的。

课题设计目的与设计意义2、课题设计意义:哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。

树中从根到每一个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或者“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。

哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。

指导教师:年月日第一章需求分析 (1)第二章设计要求 (1)第三章概要设计 (2)(1)其主要流程图如图 1-1 所示。

(3)(2)设计包含的几个方面 (4)第四章详细设计 (4)(1)①哈夫曼树的存储结构描述为: (4)(2)哈弗曼编码 (5)(3)哈弗曼译码 (7)(4)主函数 (8)(5)显示部份源程序: (8)第五章调试结果 (10)第六章心得体味 (12)第七章参考文献 (12)附录: (12)在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,时常应用于数据压缩。

哈弗曼编码使用一张特殊的编码表将源字符 (例如某文件中的一个符号) 进行编码。

哈夫曼树编码实验报告

哈夫曼树编码实验报告

哈夫曼树编码实验报告哈夫曼树编码实验报告引言:哈夫曼树编码是一种常用的数据压缩算法,通过对数据进行编码和解码,可以有效地减小数据的存储空间。

本次实验旨在探究哈夫曼树编码的原理和应用,并通过实际案例验证其有效性。

一、哈夫曼树编码原理哈夫曼树编码是一种变长编码方式,根据字符出现的频率来确定不同字符的编码长度。

频率较高的字符编码较短,频率较低的字符编码较长,以达到最佳的数据压缩效果。

1.1 字符频率统计首先,需要对待编码的数据进行字符频率统计。

通过扫描数据,记录每个字符出现的次数,得到字符频率。

1.2 构建哈夫曼树根据字符频率构建哈夫曼树,频率较低的字符作为叶子节点,频率较高的字符作为父节点。

构建哈夫曼树的过程中,需要使用最小堆来维护节点的顺序。

1.3 生成编码表通过遍历哈夫曼树,从根节点到每个叶子节点的路径上的左右分支分别赋予0和1,生成对应的编码表。

1.4 数据编码根据生成的编码表,将待编码的数据进行替换,将每个字符替换为对应的编码。

编码后的数据长度通常会减小,实现了数据的压缩。

1.5 数据解码利用生成的编码表,将编码后的数据进行解码,恢复原始数据。

二、实验过程与结果为了验证哈夫曼树编码的有效性,我们选择了一段文本作为实验数据,并进行了以下步骤:2.1 字符频率统计通过扫描文本,统计每个字符出现的频率。

我们得到了一个字符频率表,其中包含了文本中出现的字符及其对应的频率。

2.2 构建哈夫曼树根据字符频率表,我们使用最小堆构建了哈夫曼树。

频率较低的字符作为叶子节点,频率较高的字符作为父节点。

最终得到了一棵哈夫曼树。

2.3 生成编码表通过遍历哈夫曼树,我们生成了对应的编码表。

编码表中包含了每个字符的编码,用0和1表示。

2.4 数据编码将待编码的文本数据进行替换,将每个字符替换为对应的编码。

编码后的数据长度明显减小,实现了数据的压缩。

2.5 数据解码利用生成的编码表,将编码后的数据进行解码,恢复原始文本数据。

哈夫曼编译码器实验报告

哈夫曼编译码器实验报告

哈夫曼编码/译码器1. 问题描述利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。

对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

试为这样的信息收发站编写一个赫夫曼码的编/译码系统。

2.基本要求一个完整的系统应具有以下功能:(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 中。

3.测试数据(1) 已知某系统在通信联络中只可能出现八种字符,其频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计赫夫曼编码。

(2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“4.实现提示(1) 编码结果以文本方式存储在文件Codefile中。

(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。

请用户键入一个选择功能符。

此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

哈夫曼编/译码的设计与实现实验报告问题描述利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。

对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

试为这样的信息收发编写一个哈夫曼码的编/译码系统。

基本要求(1)接收原始数据:从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree.dat中。

(2)编码:利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入),对文件中的正文进行编码,然后将结果存入文件codefile.dat中。

(3)译码:利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat中。

(4)打印编码规则:即字符与编码的一一对应关系。

运行与调试(1)利用教科书中的数据调试程序。

(2)用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS-PROGRAM-IS-MY-FA VORITE”。

字符 A B C D E F G H I J K L M 频度186 64 13 22 32 103 21 15 47 57 1 5 32 20 字符N O P Q R S T U V W X Y Z频度57 63 15 1 48 51 80 23 8 18 1 16 1实验小结通过这次实验,让我对于树的应用多了认识,在读取文件时,遇到的一些困难,不过在和同学交流的过程中,解决了这个问题,我觉的自己对于树及文件的应用又有了一些进步。

通过这次实验,感觉收获很大。

源程序// 哈夫曼编译码的设计与实现.cpp : 定义控制台应用程序的入口点。

//#include "stdafx.h"#include<iostream>#include<fstream>#include<string>#define Maxvalue 10000#define MAXBIT 200using namespace std;struct node{char letter;string num;};typedef struct{char letter;int weight; //结点权值int parent;int lchild;int rchild;}HnodeType;typedef struct{int bit[MAXBIT];int start;}HcodeType;HnodeType *HaffmanTree(int n){HnodeType *HuffNode;HuffNode=new HnodeType[2*n-1];int i,j;int m1,m2,x1,x2;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;}cout<<"请输入每个叶子结点的字母和权值(形如A5):"<<endl;for(i=0;i<n;i++)cin>>HuffNode[i].letter>>HuffNode[i].weight; //输入n个叶子结点的权值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;}else{if(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;}cout<<" weight"<<" lchild"<<" rchild"<<" parent"<<endl; for(i=0;i<2*n-1;i++)cout<<i<<"--"<<" "<<HuffNode[i].weight<<" "<<HuffNode[i].lchild<<" "<<HuffNode[i].rchild<<" "<<HuffNode[i].parent<<endl;ofstream outFile("hfmtree.dat",ios::out);if(!outFile)cerr<<"文件打开失败!"<<endl;else{outFile<<" weight"<<" lchild"<<" rchild"<<"parent"<<endl;for(i=0;i<2*n-1;i++)outFile<<i<<"--"<<" "<<HuffNode[i].weight<<""<<HuffNode[i].lchild<<" "<<HuffNode[i].rchild<<""<<HuffNode[i].parent<<endl;outFile.close();}return HuffNode;}void HaffmanCode(HnodeType *HuffNode,int n){HcodeType *HuffCode,cd;HuffCode=new HcodeType[2*n-1];int c,p,i,j;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++){cout<<HuffNode[i].letter;for(j=HuffCode[i].start+1;j<n;j++)cout<<HuffCode[i].bit[j];cout<<endl;}ofstream outFile1("codefile.dat",ios::out|ios::binary);if(!outFile1)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<n;i++){outFile1<<HuffNode[i].letter;for(j=HuffCode[i].start+1;j<n;j++)outFile1<<HuffCode[i].bit[j];outFile1<<endl;}outFile1.close();}}int _tmain(int argc, _TCHAR* argv[]){HnodeType *HuffNode;int n,i;cout<<"请输入叶子结点个数:";cin>>n;if(cin.fail()){cout<<"输入有误!"<<endl;return 0;}HuffNode=HaffmanTree(n);HaffmanCode(HuffNode,n);int num;cout<<"请输入要加密的字母串的长度(空格也要计算在内):";cin>>num;char *l1;char l;node l2[27];l1=new char[num];cout<<"请输入要加密的字母串(请用大写,如有空格请用“-”代替):";for(int n=0;n<num;n++)cin>>l1[n];ofstream outFile2("bianma.dat",ios::out|ios::binary);if(!outFile2)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<num;i++)outFile2<<l1[i];outFile2.close();}ifstream inFile1("codefile.dat",ios::in|ios::binary);ifstream inFile2("bianma.dat",ios::in|ios::binary);cerr<<"读取文件失败!"<<endl;if(!inFile2)cerr<<"读取文件失败!"<<endl;else{while(inFile2.peek ()!=EOF){inFile2>>l;for(i=0;i<2*n-1;i++){inFile1>>l2[i].letter;inFile1>>l2[i].num;}for(i=0;i<n;i++){if(l2[i].letter==l)cout<<l2[i].num<<" ";}}inFile1.close();inFile2.close();}delete []l1;cout<<endl;int a;cout<<"请输入要进行译码的串的个数:";cin>>a;string *s;s=new string[a];cout<<"请输入要解码的串(每输入一个串,请按一次【Enter】键):"<<endl; for(i=0;i<a;i++)cin>>s[i];ofstream outFile4("yima.dat",ios::out);if(!outFile4)cerr<<"文件打开失败!"<<endl;else{for(i=0;i<a;i++)outFile4<<s[i]<<endl;outFile4.close();}ifstream inFile3("codefile.dat",ios::in|ios::binary);cerr<<"读取文件失败!"<<endl;else{for(i=0;i<2*n-1;i++){inFile3>>l2[i].letter;inFile3>>l2[i].num;}ifstream inFile4("yima.dat",ios::in);if(!inFile4)cerr<<"读取文件失败!"<<endl;else{for(int j=0;j<a;j++)inFile4>>s[j];}for(int j=0;j<a;j++){for(i=0;i<n;i++){if(l2[i].num==s[j])cout<<l2[i].letter;}}inFile3.close();}return 0;}。

相关文档
最新文档