哈夫曼编码实验报告材料.docx
- 文档编号:7421254
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:15
- 大小:26.42KB
哈夫曼编码实验报告材料.docx
《哈夫曼编码实验报告材料.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码实验报告材料.docx(15页珍藏版)》请在冰豆网上搜索。
哈夫曼编码实验报告材料
数
据
结
构
实
验
班级:
软件
一.实验目的
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编码/译码系统。
试为这样的信息收发站写一个哈夫曼编码的编码/译码器。
源程序
#include
#include
#include
#include
#include
//typedefintTElemType;
constintUINT_MAX=1000;
charstr[50];
typedefstruct
{
intweight,K;
intparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
//-----------全局变量-----------------------
HuffmanTreeHT;
HuffmanCodeHC;
intw[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为最大的权值1000
for(j=1;j<=i;j++)
if(t[j].weight 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(s1>s2) { j=s1; s1=s2; s2=j; } }- voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn) {//w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC intm,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和s2 select(HT,i-1,s1,s2); HT[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'; else cd[--start]='1'; HC[i]=(char*)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间 strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC } free(cd);//释放工作空间 } //---------------------获取报文并写入文件--------------------------------- intInputCode() { //cout<<"请输入你想要编码的字符"< FILE*tobetran; if((tobetran=fopen("tobetran.txt","w"))==NULL) { cout<<"不能打开文件"< return0; } cout<<"请输入你想要编码的字符"< gets(str); fputs(str,tobetran); cout<<"获取报文成功"< fclose(tobetran); returnstrlen(str); } //--------------初始化哈夫曼链表--------------------------------- voidInitialization() {inta,k,flag,len; a=0; len=InputCode(); for(i=0;i {k=0;flag=1; cou[i-a].data=str[i]; cou[i-a].count=1; while(i>k) { if(str[i]==str[k]) { a++; flag=0; } k++; if(flag==0) break; } if(flag) { for(j=i+1;j {if(str[i]==str[j]) ++cou[i-a].count;} } } n=len-a; for(i=0;i {cout< cout< } for(i=0;i<=n;i++) {*(z+i)=cou[i].data; *(w+i)=cou[i].count; } HuffmanCoding(HT,HC,w,n); //------------------------打印编码------------------------------------------- cout<<"字符对应的编码为: "< for(i=1;i<=n;i++) { puts(HC[i]); } //--------------------------将哈夫曼编码写入文件------------------------ cout<<"下面将哈夫曼编码写入文件"< FILE*htmTree; charr[]={'','\0'}; if((htmTree=fopen("htmTree.txt","w"))==NULL) { cout<<"cannotopenfile"< return; } fputs(z,htmTree); for(i=0;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中"< } //---------------------编码函数--------------------------------- voidEncoding() { cout<<"下面对目录下文件tobetran.txt中的字符进行编码"< FILE*tobetran,*codefile; if((tobetran=fopen("tobetran.txt","rb"))==NULL) { cout<<"不能打开文件"< } if((codefile=fopen("codefile.txt","wb"))==NULL) { cout<<"不能打开文件"< } char*tran; i=99; tran=(char*)malloc(100*sizeof(char)); while(i==99) { if(fgets(tran,100,tobetran)==NULL) { cout<<"不能打开文件"< 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(j>n) { cout<<"字符错误,无法编码! "< break; } } } } } cout<<"编码工作完成"< fclose(tobetran); fclose(codefile); free(tran); } //-----------------译码函数--------------------------------- voidDecoding() { cout<<"下面对根目录下文件codefile.txt中的字符进行译码"< FILE*codef,*txtfile; if((txtfile=fopen("txtfile.txt","w"))==NULL) { cout<<"不能打开文件"< } if((codef=fopen("codefile.txt","r"))==NULL) { cout<<"不能打开文件"< } char*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<<"译码完成"< free(work); free(work2); fclose(txtfile); fclose(codef); } //-----------------------打印编码的函数---------------------- voidCode_printing() { cout<<"下面打印根目录下文件CodePrin.txt中编码字符"< FILE*CodePrin,*codefile; if((CodePrin=fopen("CodePrin.txt","w"))==NULL) { cout<<"不能打开文件"< return; } if((codefile=fopen("codefile.txt","r"))==NULL) { cout<<"不能打开文件"< return; } char*work3; work3=(char*)malloc(51*sizeof(char)); do { if(fgets(work3,51,codefile)==NULL) { cout<<"不能读取文件"< break; } fputs(work3,CodePrin); puts(work3); }while(strlen(work3)==50); free(work3); cout<<"打印工作结束"< fclose(CodePrin); fclose(codefile); } //-------------------------------打印译码函数--------------------------------------------- voidCode_printing1() { cout<<"下面打印根目录下文件txtfile.txt中译码字符"< FILE*CodePrin1,*txtfile; if((CodePrin1=fopen("CodePrin1.txt","w"))==NULL) { cout<<"不能打开文件"< return; } if((txtfile=fopen("txtfile.txt","r"))==NULL) { cout<<"不能打开文件"< return; } char*work5; work5=(char*)malloc(51*sizeof(char)); do { if(fgets(work5,51,txtfile)==NULL) { cout<<"不能读取文件"< break; } fputs(work5,CodePrin1); puts(work5); }while(strlen(work5)==50); free(work5); cout<<"打印工作结束"< fclose(CodePrin1); fclose(txtfile); } //------------------------打印哈夫曼树的函数----------------------- voidcoprint(HuffmanTreestart,HuffmanTreeHT) { if(start! =HT) { FILE*TreePrint; if((TreePrint=fopen("TreePrint.txt","a"))==NULL) {cout<<"创建文件失败"< return; } numb++;//该变量为已被声明为全局变量 coprint(HT+start->rchild,HT); cout< fprintf(TreePrint,"%d\n",start->weight); coprint(HT+start->lchild,HT); numb--; fclose(TreePrint); } } voidTree_printing(HuffmanTreeHT,intw) { HuffmanTreep; p=HT+w; cout<<"下面打印哈夫曼树"< coprint(p,HT); cout<<"打印工作结束"< } //------------------------主函数------------------------------------ voidmain() { charchoice; while(choice! ='q') {cout<<"\n******************************"< cout<<"欢迎使用哈夫曼编码解码系统"< cout<<"******************************"< cout<<" (1)要初始化哈夫曼链表请输入'i'"< cout<<" (2)要编码请输入'e'"< cout<<"(3)要译码请输入'd'"< cout<<"(4)要打印编码请输入'p'"< cout<<"(5)要打印哈夫曼树请输入't'"< cout<<"(6)要打印译码请输入'y'"< if(flag==0)cout<<"\n请先初始化哈夫曼链表,输入'i'"< cin>>choice; switch(choice) { case'i': Initialization(); break; case'e': Encoding(); break; case'd': Decoding(); break; case'p': Code_printing(); break; case't': Tree_printing(HT,2*n-1); break; case'y': Code_printing1(); break; default: cout<<"inputerror"< } } free(z); free(w); free(HT); } 运行结果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 编码 实验 报告 材料