哈夫曼编码实验报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

哈夫曼编码器实验报告学院:计算机学院班级:计科0801班姓名:王宇宏学号:04081027(27)2一.实验目的练习树和哈夫曼树的有关操作,和各个算法程序,理解哈夫曼树的编码和译码二.实验环境Microsoftvisualc++三、问题描述利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编码/译码系统。试为这样的信息收发站写一个哈夫曼编码的编码/译码器。四、需求分析(1)初始化;从终端输入字符集的大小n,以及n个字符和n个权值建立哈夫曼树。(2)输出哈夫曼树,及各字符对应的编码。(3)编码:利用建好的哈夫曼树,对输入的待发送电文进行编码。同时输入原文及编码串。(4)译码:利用建好的哈夫曼树,对输入的已接收电文进行译码。同时输入编码串及原文。五、概要设计#includeiostream.h#includeiomanip.h#includestring.h#includemalloc.h#includestdio.h//typedefintTElemType;constintUINT_MAX=1000;charstr[50];typedefstruct{intweight,K;intparent,lchild,rchild;}HTNode,*HuffmanTree;typedefchar**HuffmanCode;//-----------全局变量-----------------------HuffmanTreeHT;HuffmanCodeHC;3intw[50],i,j,n;charz[50];intflag=0;intnumb=0//-----------------求哈夫曼编码-----------------------structcou{chardata;intcount;}cou[50];intmin(HuffmanTreet,inti){//函数voidselect()调用intj,flag;intk=UINT_MAX;//取k为不小于可能的值,即k为最大的权值1000for(j=1;j=i;j++)if(t[j].weightk&&t[j].parent==0)k=t[j].weight,flag=j;t[flag].parent=1;returnflag;}//--------------------slect函数----------------------voidselect(HuffmanTreet,inti,int&s1,int&s2){//s1为最小的两个值中序号小的那个intj;s1=min(t,i);s2=min(t,i);if(s1s2){j=s1;s1=s2;s2=j;}}//--------------算法6.12--------------------------voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn){//w存放n个字符的权值(均0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HCintm,i,s1,s2,start;//unsignedc,f;intc,f;HuffmanTreep;char*cd;if(n=1)return;//检测结点数是否可以构成树m=2*n-1;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用for(p=HT+1,i=1;i=n;++i,++p,++w){p-weight=*w;p-parent=0;p-lchild=0;p-rchild=0;}for(;i=m;++i,++p)p-parent=0;for(i=n+1;i=m;++i)//建哈夫曼树{//在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2select(HT,i-1,s1,s2);4HT[s1].parent=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个字符编码的头指针向量([0]不用)cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间cd[n-1]='\0';//编码结束符for(i=1;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';elsecd[--start]='1';HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC}free(cd);//释放工作空间}//---------------------获取报文并写入文件---------------------------------intInputCode(){//cout请输入你想要编码的字符endl;FILE*tobetran;if((tobetran=fopen(tobetran.txt,w))==NULL){cout不能打开文件endl;return0;}cout请输入你想要编码的字符endl;gets(str);fputs(str,tobetran);cout获取报文成功endl;fclose(tobetran);returnstrlen(str);}//--------------初始化哈夫曼链表---------------------------------voidInitialization(){inta,k,flag,len;a=0;len=InputCode();for(i=0;ilen;i++){k=0;flag=1;cou[i-a].data=str[i];cou[i-a].count=1;while(ik){if(str[i]==str[k]){a++;5flag=0;}k++;if(flag==0)break;}if(flag){for(j=i+1;jlen;j++){if(str[i]==str[j])++cou[i-a].count;}}}n=len-a;for(i=0;in;i++){coutcou[i].data;coutcou[i].countendl;}for(i=0;i=n;i++){*(z+i)=cou[i].data;*(w+i)=cou[i].count;}HuffmanCoding(HT,HC,w,n);//------------------------打印编码-------------------------------------------cout字符对应的编码为:endl;for(i=1;i=n;i++){puts(HC[i]);}//--------------------------将哈夫曼编码写入文件------------------------cout下面将哈夫曼编码写入文件endl....................endl;FILE*htmTree;charr[]={'','\0'};if((htmTree=fopen(htmTree.txt,w))==NULL){coutcannotopenfileendl;return;}fputs(z,htmTree);for(i=0;in+1;i++){fprintf(htmTree,%6d,*(w+i));fputs(r,htmTree);}for(i=1;i=n;i++){fputs(HC[i],htmTree);fputs(r,htmTree);}fclose(htmTree);cout已将字符与对应编码写入根目录下文件htmTree.txt中endlendl;}//---------------------编码函数---------------------------------6voidEncoding(){cout下面对目录下文件tobetran.txt中的字符进行编码endl;FILE*tobetran,*codefile;if((tobetran=fopen(tobetran.txt,rb))==NULL){cout不能打开文件endl;}if((codefile=fopen(codefile.txt,wb))==NULL){cout不能打开文件endl;}char*tran;i=99;tran=(char*)malloc(100*sizeof(char));while(i==99){if(fgets(tran,100,tobetran)==NULL){cout不能打开文件endl;break;}for(i=0;*(tran+i)!='\0';i++){for(j=0;j=n;j++){if(*(z+j-1)==*(tran+i)){fputs(HC[j],codefile);if(jn){cout字符错误,无法编码!endl;break;}}}}}cout编码工作完成endl编码写入目录下的codefile.txt中endlendl;fclose(tobetran);fclose(codefile);free(tran);}//-----------------译码函数---------------------------------voidDecoding(){cout下面对根目录下文件codefile.txt中的字符进行译码endl;FILE*codef,*txtfile;if((txtfile=fopen(txtfile.txt,w))==NULL){cout不能打开文件endl;}if((codef=fopen(codefile.txt,r))==NULL){cout不能打开文件endl;}7char*work,*work2,i2;inti4=0,i,i3;unsignedlonglength=10000;work=(char*)malloc(length*sizeof(char));fgets(work,length,codef);work2=(char*)malloc(length*sizeof(char));i3=2*n-1;for(i=0;*(work+i-1)!='\0';i++){i2=*(work+i);if(HT[i3].lchild==0){*(work2+i4)=*(z+i3-1);i4++;i3=2*n-1;i--;}elseif(i2=='0')i3=HT[i3].lchild;elseif(i2=='1')i3=HT[i3].rchild;}*(work2+i4)='\0';fputs(work2,txtfile);cout译码完成endl内容写入根目录下的文件txtfile.txt中endlendl;free(work);free(work2);fclose(txtfile);fclose(codef);}//-----------------------打印编

1 / 13
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功