目录一、摘要 (3)二、题目 (3)三、实验目的 (3)四、实验原理 (3)五、需求分析 (4)5.1实验要求 (4)5.2实验内容 (4)六、概要设计 (4)6.1所实现的功能函数 (4)6.2主函数 (5)6.3 系统结构图 (6)七、详细设计和编码 (6)八、运行结果 (12)九、总结 (15)9.1调试分析 (15)9.2 心得体会 (15)参考文献 (16)一、摘要二、题目哈夫曼树的编码与译码三、实验目的(1)熟悉对哈夫曼的应用以及构造方法,熟悉对树的构造方式的应用;(2)进一步掌握哈夫曼树的含义;(3)掌握哈夫曼树的结构特征,以及各种存储结构的特点以及使用范围;(4)熟练掌握哈夫曼树的建立和哈夫曼编码方法;(5)提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法;(6)掌握一种计算机语言,可以进行数据算法的设计。
四、实验原理哈夫曼(Huffman)编码属于长度可变的编码类,是哈夫曼在1952年提出的一种编码方法,即从下到上的编码方法。
同其他码词长度一样,可区别的不同码词的生成是基于不同符号出现的不同概率。
生成哈夫曼编码算法基于一种称为“编码树”(coding tree)的技术。
算法步骤如下:(1)初始化,根据富豪概率的大小按由大到小顺序对符号进行排序;(2)把概率最小的两个符号组成一个新符号(节点),即新符号的概率等于这两个符号概率之和;(3)重复第(2)步,直到形成一个符号为止(树),其概率最后等于1;(4)从编码树的根开始回溯到原始的符号,并将每一下分支赋值1,上分支赋值0;译码的过程是分解电文中字符串,从根出发,按字符“0”或者“1”确定找做孩子或右孩子,直至叶子节点,便求得该子串相应的字符。
五、需求分析5.1实验要求(1)从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树的存储结构;(2)利用已经建好的哈夫曼树,对给定的n个字符正文进行编码,并输出结果。
(3)利用已建好的哈夫曼树,对给定的一个哈夫曼编码进行译码,判断此编码对应的字符,并输出结果。
5.2实验内容(1)定义哈夫曼树结构;(2)初始化哈夫曼树,存储哈夫曼树信息;(3)定义哈夫曼编码的函数;(4)定义哈夫曼译码的函数;(5)写出主函数;(6)测试系统;(7)运行程序。
六、概要设计6.1所实现的功能函数void initHuffmanTree();//初始化哈夫曼树int inputInit();//进行哈夫曼树的初始化int HuffmanCoding(int *w); //初始化哈夫曼数,按照哈夫曼规则建立二叉树。
此函数块调用了Select()函数。
void Select(int j,int &s1,int &s2); //选择parent为0,且weight最小的两个节点序号为s1,s2void encoding();//哈夫曼编码void inputEnco();//进行哈夫曼编码void decode();//哈夫曼译码void inputDeco();//进行哈夫曼译码6.2主函数int main(){int sel=0;cout<<"Xin Yun"<<endl;cout<<"Information Safety of 2"<<endl;cout<<"Welcome to use the coding and decode of Huffman!"<<endl;for(;;){cout<<"\t*\t"<<"1.init"<<endl;cout<<"\t*\t"<<"2.coding"<<endl;cout<<"\t*\t"<<"3.decode"<<endl;cout<<"\t*\t"<<"4.quit"<<endl;cout<<"Please input your choice(1-4)."<<endl<<" ";cin>>sel;if(sel==4) break;switch(sel){case 1:initHuffmanTree();break;case 2:encoding();break;case 3:decode();break;default:cout<<"Sorry!The number you have input is wrong!"<<endl;}}outstuf.close();cout<<"Thank you to use it!!!"<<endl;return 0;}解析:挑选需要实现的功能(1)当输入“1”时,调用initHuffmanTree()函数,进行哈夫曼树的初始化;(2)当输入“2”时,调用encoding()函数,进行哈夫曼树的编码;(3)当输入“3”时,调用decode()函数,进行哈夫曼树的译码;(4)当输入“4”时,退出程序;6.3 系统结构图七、详细设计和编码#include<iostream>#include<fstream>#include<cstring>using namespace std;ofstream outstuf;typedef struct{unsigned int weight;unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree;typedef char** HuffmanCode;HuffmanTree HT=NULL;int n=0;HuffmanCode HC=NULL;char *ch=NULL;void initHuffmanTree();int inputInit();int HuffmanCoding(int *w);void Select(int j,int &s1,int &s2);void encoding();void inputEnco();void decode();void inputDeco();void initHuffmanTree(){inputInit();}int inputInit(){cout<<"Please input the number of the character(n).\t";cin>>n;int *w=(int *)malloc((n+1)*sizeof(int));if(!w) {cout<<"ERROR";return 0;}ch=(char *)malloc((n+1)*sizeof(char));if(!ch) {cout<<"ERROR";return 0;}cout<<" Please input the characters.\t";for(int i=1;i<=n;i++) cin>>ch[i];cout<<"Please input the numbers.\t";for(i=1;i<=n;i++) cin>>w[i];outstuf.open("hfmTree.txt",ios::out);for(i=1;i<=n;i++){outstuf<<ch[i]; outstuf<<w[i];};cout<<endl;HuffmanCoding(w);cout<<"The coding of every character is:";for(i=1;i<=n;i++) {cout<<" "<<ch[i]<<'\t';cout<<HC[i];} ;outstuf.close();outstuf.open("code.txt",ios::out);for(i=1;i<=n;i++){outstuf<<ch[i]; outstuf<<HC[i];};cout<<endl;outstuf.close();return 0;}int HuffmanCoding(int *w){if(n<=1) return 1;int m=2*n-1;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));if(!HT) {cout<<"ERROR";return 0;}for(int i=1; i<=n; ++i){HT[i].weight=w[i];HT[i].parent=HT[i].lchild=HT[i].rchild=0;}for(;i<=m; ++i) HT[i].weight=HT[i].parent=HT[i].lchild=HT[i].rchild=0;int s1=0;int s2=0;for(i=n+1;i<=m; ++i){Select(i-1, s1, s2);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*));char *cd=(char*) malloc(n*sizeof(char));if(!cd) {cout<<"ERROR";return 0;}cd[n-1]='\0';int start;for(i=1;i<=n;++i){start=n-1;for(int c=i,unsigned int 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));strcpy(HC[i],&cd[start]);}free(cd);return 0;}void Select(int j,int &s1,int &s2){for(int h=1;h<=j;h++)if(HT[h].parent==0) {s1=h;break;}h++;for(;h<=j;h++)if(HT[h].parent==0) {s2=h;break;}int m;if(HT[s1].weight>HT[s2].weight) {m=s1;s1=s2;s2=m;}h++;for(;h<=j;h++)if(HT[s1].weight>HT[h].weight&&HT[h].parent==0) s1=h;for(m=1;m<=j;m++)if(HT[s2].weight>HT[m].weight&&m!=s1&&HT[m].parent==0) s2=m;}void encoding(){inputEnco();}void inputEnco(){cout<<"Please input the sentence that you want to coding.(Please end of the character of '$')"<<endl;char *file=(char *)malloc(200*sizeof(char));for(int i=1;i<200;i++){cin>>file[i];if(file[i]=='$') break;}if(i==200) {file=(char *)realloc(file,(200+80)*sizeof(char));for(;i<280;i++){cin>>file[i];if(file[i]=='$') break;}}int m=i;cout<<"The result of the coding is:"<<endl;outstuf.open("CodeFile.txt",ios::out);for(i=1;i<m;i++){for(int j=1;j<=n;j++)if(file[i]==ch[j]) {cout<<HC[j];outstuf<<HC[j]; break;}if(j==(n+1)) {cout<<endl<<"The sentence is wrong and it can't coding! "<<endl; break;}cout<<endl;outstuf.close();}void decode(){inputDeco();}void inputDeco(){int m=2*n-1;char *password=(char *)malloc(200*sizeof(char));cout<<"Please input the sentence you want to decode.(Please end of the character of '$')"<<endl;for(int i=1;i<200&&password[i-1]!='$';i++) cin>>password[i];if(i==200) {password=(char *)realloc(password,(200+80)*sizeof(char));for(;i<280&&password[i]!='$';i++) cin>>password[i];}cout<<"The result of decode is:"<<endl;outstuf.open("TextFile.txt",ios::out);for(i=1;password[i]!='$';){char record[20];for(int j=0,q=i;password[q]!='$';j++,q++){if(password[q]=='0') {record[j]='0';m=HT[m].lchild;}else {record[j]='1';m=HT[m].rchild;}if(HT[m].rchild==0) {record[j+1]='\0';break;}}if(HT[m].rchild!=0) {cout<<endl<<"The sentence is wrong and it can't decode!"<<endl;break;}for(int p=1;p<=n;p++){if(!strcmp(record,HC[p])) {outstuf<<ch[p]; cout<<ch[p];break;}}i=i+strlen(record);m=2*n-1;}cout<<endl;outstuf.close();}int main(){int sel=0;cout<<"Xin Yun"<<endl;cout<<"Information Safety of 2"<<endl;cout<<"Welcome to use the coding and decode of Huffman!"<<endl;for(;;){cout<<"\t*\t"<<"1.init"<<endl;cout<<"\t*\t"<<"2.coding"<<endl;cout<<"\t*\t"<<"3.decode"<<endl;cout<<"\t*\t"<<"4.quit"<<endl;cout<<"Please input your choice(1-4)."<<endl<<" ";cin>>sel;if(sel==4) break;switch(sel){case 1:initHuffmanTree();break;case 2:encoding();break;case 3:decode();break;default:cout<<"Sorry!The number you have input is wrong!"<<endl;}}outstuf.close();cout<<"Thank you to use it!!!"<<endl;return 0;八、运行结果图表1开始界面图表2哈夫曼树的初始化图表3哈夫曼树的编码图表4哈夫曼树的译码图表5退出界面图表6全部九、总结9.1调试分析在写程序和调试的过程中,在对函数的理解及调用、参数的传递等方面遇到了很多的麻烦和困难;但最终在同学和老师的帮助下,我最终找出了程序中的错误并将其修改正确,通过分析,我学到了很多。