哈夫曼编解码 完整c程序代码
c语言实现哈夫曼算法

c语言实现哈夫曼算法以下是C语言实现哈夫曼算法的示例代码:```cinclude <>include <>include <>// 定义哈夫曼树节点结构体typedef struct HuffmanNode {char data; // 节点存储的数据int freq; // 节点出现的频率struct HuffmanNode left, right; // 左右子树指针} HuffmanNode;// 定义创建哈夫曼树函数HuffmanNode createNode(char data, int freq) { HuffmanNode node =(HuffmanNode)malloc(sizeof(HuffmanNode));node->data = data;node->freq = freq;node->left = node->right = NULL;return node;}// 定义比较函数,用于按照频率从小到大排序int compare(const void a, const void b) {return ((HuffmanNode)b)->freq - ((HuffmanNode)a)->freq; }// 定义构建哈夫曼树函数HuffmanNode buildHuffmanTree(char data[], int freq[], int size) { if (size == 1) {return createNode(data[0], freq[0]);} else {HuffmanNode nodes[size]; // 存储所有节点指针的数组for (int i = 0; i < size; i++) {nodes[i] = createNode(data[i], freq[i]);}qsort(nodes, size, sizeof(HuffmanNode), compare); // 按频率从小到大排序return mergeNodes(nodes, size); // 合并两个最小的节点,直到只剩下一个节点}}// 定义合并两个最小节点函数HuffmanNode mergeNodes(HuffmanNode nodes[], int size) {if (size == 0) return NULL; // 空节点返回NULL指针if (size == 1) return nodes[0]; // 只剩下一个节点直接返回该节点指针 HuffmanNode root = createNode('$', nodes[0]->freq + nodes[1]->freq); // 创建根节点,频率为左右子树频率之和root->left = mergeNodes(nodes+1, size-1); // 递归合并剩余节点,左子树指向左子树数组中除第一个节点外的所有节点指针,右子树指向右子树数组中除最后一个节点外的所有节点指针return root; // 返回根节点指针}```。
哈夫曼编码算法实现完整版

实验三树的应用一.实验题目:树的应用——哈夫曼编码二.实验内容:利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。
根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。
要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。
三、程序源代码:#include <iostream.h>#include <fstream.h>#include <string.h>#include <stdlib.h>typedef struct{char data;int weight;int parent,lchild,rchild;}HTNode,*HuffmanTree;typedef char * * HuffmanCode;void Select(HuffmanTree &HT,int n,int m){HuffmanTree p=HT;int tmp;for(int j=n+1;j<=m;j++){int tag1,tag2,s1,s2;tag1=tag2=32767;for(int x=1;x<=j-1;x++){ if(p[x].parent==0&&p[x].weight<tag1){ tag1=p[x].weight;s1=x;}}for(int y=1;y<=j-1;y++){ if(p[y].parent==0&&y!=s1&&p[y].weight<tag2){ tag2=p[y].weight;s2=y;}}if(s1>s2) //将选出的两个节点中的序号较小的始终赋给s1{ tmp=s1; s1=s2; s2=tmp;}p[s1].parent=j;p[s2].parent=j;p[j].lchild=s1;p[j].rchild=s2;p[j].weight=p[s1].weight+p[s2].weight;}}void HuffmanCoding(HuffmanTree &HT,int n,char *w1,int*w2){int m=2*n-1;if(n<=1) return;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));HuffmanTree p=HT;for(int i=1;i<=n;i++){ p[i].data=w1[i-1];p[i].weight=w2[i];p[i].parent=p[i].lchild=p[i].rchild=0;}for(;i<=m;i++){ p[i].weight=p[i].parent=p[i].lchild=p[i].rchild=0; }Select(HT,n,m);ofstream outfile; //生成hfmTree文件outfile.open("hfmTree.txt",ios::out);for (i=1;i<=m;i++){outfile<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<"\t"<<endl;}outfile.close();cout<<"初始化结果已保存在hfmTree文件中\n";}void ToBeTree() //将正文写入文件ToBeTree中{ofstream outfile;outfile.open("ToBeTree.txt",ios::out);outfile<<"THIS PROGRAM IS MYFA VORITE";outfile.close();}void Encoding(HuffmanTree &HT,int n) //编码{HuffmanCode HC;HC=(HuffmanCode)malloc((n+1)*sizeof(char *));char *cd;cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(int k=1;k<=n;k++){ int start=n-1;for(int c=k,f=HT[k].parent;f!=0;c=f,f=HT[f].parent){ if(HT[f].lchild==c) cd[--start]='0';else cd[--start]='1';}HC[k]=(char *)malloc((n-start)*sizeof(char));strcpy(HC[k],&cd[start]);}cout<<"输出哈夫曼编码:"<<endl;for(int h=1;h<=n;h++) //输出编码{ cout<<HT[h].data<<":";cout<<HC[h];cout<<" ";if (h%8==0) cout<<endl;}cout<<endl<<"输出正文编码:"<<endl;ToBeTree();//读取TOBETREE文件里的正文,并进行编码fstream infile;infile.open("ToBeTree.txt",ios::in);char s[80];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();fstream outfile;outfile.open("CodeFile.txt",ios::out);int count=0;for (h=0;s[h]!='\0';h++){ for(k=1;k<=n;k++)if (s[h]==HT[k].data){ cout<<HC[k];cout<<" ";count++;outfile<<HC[k];break;}if (count%9==0) cout<<endl; //每输出7个换行}outfile.close();cout<<"\n编码结果已保存在文件CodeFile中.";cout<<endl;}void Decoding(HuffmanTree &HT,int n) //译码{int f=2*n-1;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();int i=0;int j=0;fstream outfile;outfile.open("TextFile.txt",ios::out);while(s[i]!='\0'){ f=2*n-1;while(HT[f].lchild!=0)//以f对应的节点的左孩子的值==0作为结束{if (s[j]=='0') f=HT[f].lchild;else f=HT[f].rchild;j++;}i=j;cout<<HT[f].data;outfile<<HT[f].data;}outfile.close();cout<<"\n译码结果已保存在文件TextFile中.";cout<<endl;}void Print() //印代码文件{ int count=0;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));for(int i=0;s[i]!='\0';i++){ cout<<s[i];count++;if (count%50==0) cout<<endl; //在终端上每行显示50个代码}}infile.close();cout<<endl;}char menu() //菜单函数{ cout<<"功能菜单如下:"<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<" I:初始化(Initialization) "<<endl;cout<<" E:编码(Encoding) "<<endl;cout<<" D:译码(Decoding) "<<endl;cout<<" P:印代码文件(Print) "<<endl;cout<<" Q:退出(Exit) "<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<"请输入功能字符:";char ch;cin>>ch;return ch;}void main(){ int n;int Array[100];char cArray[100];HuffmanTree HT;cout<<"输入n个字符:";cin.getline(cArray,100);n=strlen(cArray);cout<<"一共"<<n<<"个字符.\n";cout<<"依次输入各个字符的权值:"<<endl;for (int i=1;i<=n;i++) cin>>Array[i];int tag;char x=menu();while(1){ switch (x){case 'I':HuffmanCoding(HT,n,cArray,Array);break;case 'E':Encoding(HT,n);break;case 'D':Decoding(HT,n);break;case 'P':Print();break;case 'Q':tag=0;cout<<"结束"<<endl;break;default:cout<<"你输入错误!"<<endl;}if(tag==0) break;cout<<"y(继续) or n(退出)"<<endl;char ch;cin>>ch;if (ch=='y'){ cout<<"请输入功能字符:";char c;cin>>c;x=c;}else exit(1);}}测试数据:用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的译码和编码:"THIS PROGRAM IS MY FAVORITE".字符空格 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四.测试结果:如图一所示五.实验体会通过本次实验,尤其在自己对程序的调试过程中,感觉对树的存储结构,终结状态,还有编码,译码的过程都有了比较清晰的认识。
C语言哈夫曼编码代码

#include<string.h>#include<stdlib.h>#include<stdio.h>int m,s1,s2;typedef struct {unsigned int weight;unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表void Select(HuffmanTree HT,int n) {int i,j;for(i = 1;i <= n;i++)if(!HT[i].parent){s1 = i;break;}for(j = i+1;j <= n;j++)if(!HT[j].parent){s2 = j;break;}for(i = 1;i <= n;i++)if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))s1=i; for(j = 1;j <= n;j++)if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))s2=j; }void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n) {// 算法6.13// w存放n个字符的权值(均>0),构造哈夫曼树HT,// 并求出n个字符的哈夫曼编码HCint i, j;char *cd;int p;int cdlen;if (n<=1) return;m = 2 * n - 1;HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用for (i=1; i<=n; i++) { //初始化HT[i].weight=w[i-1];HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for (i=n+1; i<=m; i++) { //初始化HT[i].weight=0;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}puts("\n哈夫曼树的构造过程如下所示:");printf("HT初态:\n 结点weight parent lchild rchild");for (i=1; i<=m; i++)printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,HT[i].parent,HT[i].lchild, HT[i].rchild);printf(" 按任意键,继续...");getchar();for (i=n+1; i<=m; i++) { // 建哈夫曼树// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,// 其序号分别为s1和s2。
哈夫曼编码译码C语言编写

哈夫曼编码译码C语言编写10[ 标签:哈夫曼,编码,译码 ]如上题 C语言编个程序懂的帮搞个能运行的程序来#11别到网上找那些我找过了没用的蝶风待夕魂回答:2 人气:19 解决时间:2009-05-14 18:44满意答案好评率:100%#include<stdio.h>#include<stdlib.h>#include<string.h>typedef char ElemType;typedef struct{ElemType elem;unsigned int weight;unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree;typedef char** HuffmanCode;typedef int Status;typedef struct {char elem;unsigned int weight;}Weight; // save the information of the symbolizes;void HuffmanCoding(HuffmanTree *,HuffmanCode *,Weight *,int);void Select(HuffmanTree,int,int *,int *);void OutputHuffmanCode(HuffmanTree,HuffmanCode,int);Status main(void){HuffmanTree HT;HuffmanCode HC;Weight *w;char c;int i,n;int wei;printf("input the tatol number of the Huffman Tree:" );scanf("%d",&n);w=(Weight *)malloc(n*sizeof(Weight));for(i=0;i<n;i++){printf("input the element & its weight:");scanf("%1s%d",&c,&wei);w[i].elem=c;w[i].weight=wei;}HuffmanCoding(&HT,&HC,w,n);OutputHuffmanCode(HT,HC,n);return 1;}回答人的补充 2009-05-08 00:07接上面的。
哈夫曼信源编码c语言程序代码

哈夫曼信源编码c语言程序代码哈夫曼编码的C语言实现编码原理程序步骤的分析:哈夫曼码是用概率匹配方法进行信源编码。
编程时应该注意:1,概率大的符号对应于短码,概率小的对应于长码,充分利用短码;2缩减信源的最后二个码字,总是最后一位不同,保证了哈夫曼码是即时码。
程序步骤:(见信息论课本p88页内容)(l)将信号源的符号按照出现概率递减的顺序排列。
(2)将两个概率最小的字母分别配以0和1两个码元,并将这两个概率相加作为一个新字母的概率(3)重排后的两个概率最小符号重复步骤(2)过程。
(4)不断继续上述过程,直到最后两个符号配以0和1为止(5)从最后一级开始向前返回各个信源符号所对应的码元序列,及相应的码字。
根据以上规则编码可知:哈夫曼编码实际上构造了一个码树,码树从最上层的端点开始构造,到树根结束,最后得到一个横放的码树,所以编出的码是即时码。
哈夫曼编码概率大的符号对应于短码,概率小的符号对应于长码,使平均码长最小。
每次对概率最小的两个符号求概率之和形成缩减信源时,构造出两个树枝,由于给两个树枝赋码元时是任意的,因此编出的码字不惟一。
程序源代码如下;#include stdio.h#include malloc.h #include conio.h #include string.h #include stdlib.h #define HuffmanTree HF #define HuffmanCode HMC typedef struct {unsigned int weight; unsigned int parent,lchild,rchild; } HTNode,*HF; typedef char **HMC; typedef struct { unsigned int s1; unsigned int s2; } MinCode; void Error(char *message); HMC HuffmanCoding(HF HT,HMC HC,unsigned int *w,unsigned int n); MinCode Select(HF HT,unsigned int n); void Error(char *message) { fprintf(stderr,“Error:%s\n",message); exit(1); } HMC HuffmanCoding(HF HT,HMC HC,unsigned int *w,unsigned int n) { unsigned int i,s1=0,s2=0; HF p; char *cd; unsigned int f,c,start,m; MinCode min; if(n=1) Error("Code too small!"); m=2*n-1;HT=(HF)malloc((m+1)*sizeof(HTNode)); for(p=HT,i=0;ii++,p++,w++) { p-weight=*w; p-parent=0; p-lchild=0; p-rchild=0; } for(;ii++,p++) { p-weight=0; p-parent=0; p-lchild=0; p-rchild=0; } for(i=n+1;ii++){ min=Select(HT,i-1); s1=min.s1; s2=min.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; } printf("HT List:\n");printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n"); for(i=1;ii++) printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);HC=(HMC)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char *)); cd[n-1]='\0'; for(i=1;ii++) { 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 *)); strcpy(HC[i],cd[start]); } free(cd); return HC; } void main() {MinCode Select(HF HT,unsigned int n); HF HT=NULL; HuffmanCode HC=NULL; unsigned int *w=NULL; unsigned int i,n; printf("请输入节点个数n:"); scanf("%d", w=(unsigned int *)malloc((n+1)*sizeof(unsigned int *));w=0; printf("请输入权重:\n"); for(i=1;ii++) { printf("w[%d]=",i);scanf("%d",w[i]); } HC=HuffmanCoding(HT,HC,w,n); printf("HMC:\n");printf("Number\t\tWeight\t\tCode\n"); for(i=1;ii++)printf("%d\t\t%d\t\t%s\n",i,w[i],HC[i]); } MinCode Select(HF HT,unsigned int n) { unsigned int min,secmin; unsigned int temp; unsigned int i,s1,s2,tempi; MinCode code;s1=1;s2=1; for(i=1;ii++) if(HT[i].parent==0) { min=HT[i].weight; s1=i; break; } tempi=i++; for(;ii++) if(HT[i].weightminHT[i].parent==0){ min=HT[i].weight; s1=i; } for(i=tempi;ii++) if(HT[i].parent==0i!=s1){ secmin=HT[i].weight; s2=i; break; } for(i=1;ii++)if(HT[i].weightsecmini!=s1HT[i].parent==0) { secmin=HT[i].weight; s2=i; } if(s1s2){ temp=s1; s1=s2; s2=temp; } code.s1=s1; code.s2=s2; return code; } 运行结果如下:请输入节点个数n:5请输入权重:w=2 w=3 w=1 w=1 w=3 Number Weight Code 1 2 00 2 3 10 3 1 010 4 1 011 5 3 11 Press any key to continue编程感想及总结:正如事物均具有两面性,哈夫曼编码也具有优点和缺点,比如哈夫曼编码可以取得较好的荣誉压缩效果,使得输出码元概率均匀化。
哈夫曼编解码 完整c程序代码

哈夫曼编解码完整c程序代码Huffman 编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在接收端进行解码。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/解码系统。
2)要求:一个完整的huffman编解码系统应该具有以下功能:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman 树,并将它存入hfmTree 中。
编码(Encoding)。
利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
解码(Decoding)。
利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
打印代码文件(Print)。
将文件CodeFile以紧凑的格式显示在终端上,每行50 个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
打印Huffman树(Tree Printing)。
将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。
3) 测试数据: 用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:“THIS PROGRAM IS MY FAVORITE”。
字符 A B C D E F G H I J K L M 频度1866413223210321154757153220 字符 N O P Q R S T U V W X Y Z 频度5763151485180238181161 完整代码如下:#include<stdio、h>#include<iostream>#include<string>#define N100int*w;char *c,stack[N],code[N][N];int s1,s2;typedef struct HuffmanTree{int weight;int parent;int lchild;int rchild;}HuffmanTree,*Huff;void menu(void); voidSelect(struct HuffmanTree HT[],int i); voidHuffmanTree(Huff &HT,int *w,int n);void visite(HuffHT,int i,int flag,int rear);void translatef(char*scource,char *save,int n);bool uncodef(FILE *fp1,FILE*fp2,Huff HT,int n);int inputHuff();void screanio(int n);void fileio(int n);int initHuff();void Print_tree(int n,Huff HT);void Convert_tree(Huff HT,unsigned charT[100][100],int tt[100][100],int s,int *i,int j);void decoding(int n);void coding(int n);void main(){intn=0;menu();Huff HT;char state;do{std::cout<<"input:\n";std::cin>>state;fflush(stdin); //读取状态switch(state){ caseI:n=inputHuff();HuffmanTree(HT,w,n);st d::cout<<"\nHuffmanTree 初始化完毕\n";break;caseC:coding(n);break; caseD:decoding(n);break;caseP:Print_tree(n,HT);break;caseQ:break;}}while(state!=Q);}void menu()//显示菜单函数{std::cout<<"===========HuffmanCoding===========\n"; std::cout<<"input \t\t do\n";std::cout<<"I\t\tInit_HUffTree\n"; //初始化huffmantreestd::cout<<"C \t\tCoding\n"; //对ToBeTran、txt文件中的字符进行编码到CodeFile、txt中std::cout<<"D \t\tUnCoding\n"; //对CodeFile、txt中的01序列进行解码到TextFile、txtstd::cout<<"P \t\tPrintTree\n"; //打印哈夫曼树std::cout<<"Q \t\tquit\n";std::cout<<"请初始化哈夫曼树再执行后面的操作\n";}int inputHuff()//输入各个字母及其权值{int i=1,n=0;int ww[28];char cc[28];while(1){std::cout<<"input the letter(input # to stop):";cc[i]=std::cin、get();fflush(stdin);if(cc[i]==#)break;std::cout<<"inputtheweight:";std::cin>>ww[i];fflush(stdin);n++;i++;}w=(int *)malloc(sizeof(int)*(n+1));c=(char*)malloc(sizeof(char)*(n+1));for(i=0;i<n+1;i++){w[i]=ww[i ];c[i]=cc[i];}return n;}void HuffmanTree(Huff &HT,int*w,int n)//初始化哈夫曼树{int m,i;m=n*2-1;HT=(struct HuffmanTree *)malloc(sizeof(structHuffmanTree)*(m+1));HT[0]、lchild=0;HT[0]、parent=0;HT[0]、rchild=0;HT[0]、weight=0;for(i=1;i<m;i++){HT[i]、weight=i<=n?w[i]:0;HT[i]、lchild=HT[i]、rchild=HT[i]、parent=0;}for(i=n+1;i<=m;i++){ Select(HT,i);HT[i]、lchild=s1;HT[i]、rchild=s2;HT[i]、weight=HT[s1]、weight+HT[s2]、weight;HT[s1]、parent=HT[s2]、parent=i;}}void Select(struct HuffmanTree HT[],int i) //在HT[1、、i-1]中选择parent为0且weight为最小的两个结点{ int j;for(j=1;j<i;j++){if(HT[j]、parent==0){s1=j;s2=j;goto flag;}}flag:for(j=s1+1;j<i;j++){if(HT[j]、parent==0){if(HT[s1]、weight >=HT[j]、weight){s2=s1;s1=j;}if(HT[s2]、weight>HT[j]、weight&&j!=s1)s2=j;if(s1==s2)s2=j;}}}void Print_tree(int n,Huff HT)//以凹入法的形式打印树{ unsigned char T[100][100];int tt[100][100]; int i,j,m=0; FILE *fp;Convert_tree(HT,T,tt,0,&m,2*n-1); //将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中if((fp=fopen("treeprint、txt","wb+"))==NULL)printf("Open file treeprint、txt error!\n");printf("\n以凹凸表形式打印已建好的赫夫曼树:\n");for(i=1;i<=2*n-1;i++){ for (j=0;T[i][j]!=0;j++){ if(T[i][j]== ){printf(" ");fputc(T[i][j],fp);} else{printf("%d",tt[i][j]);fprintf(fp,"%d\n\n\n",tt[i][j]);} } printf("\n"); } fclose(fp); printf("\n此字符形式的哈夫曼树已写入文件treeprint、txt中、\n\n"); printf("\n文件treeprint、txt的打开方式要为写字板,若打开方式为记事本,则无法显示凹凸表的形式\n"); } void Convert_tree(HuffHT,unsigned char T[100][100],int tt[100][100],int s,int*i,int j)//将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中{ int k,l; l=++(*i); for(k=0;k<s;k++)T[l][k]= ; T[l][k]=#; tt[l][k]=HT[j]、weight;if(HT[j]、lchild)Convert_tree(HT,T,tt,s+1,i,HT[j]、lchild); if(HT[j]、rchild)Convert_tree(HT,T,tt,s+1,i,HT[j]、rchild);T[l][++k]=\0; } void coding(int n)//对文件ToBeTran、txt编码到CodeFile、txt{ FILE*fp1;Huff HT;HuffmanTree(HT,w,n);visite(HT,2*n-1,2,0);fflush(stdin);translatef("ToBeTran、txt","CodeFile、txt",n);fp1=fopen("CodeFile、txt","r");printf("\n编码已写入文件treeprint、txt中、\n");fclose(fp1);}void decoding(int n)//对CodeFile、txt中的01序列进行解码到TextFile、txt{FILE *fp1,*fp2;HuffHT;HuffmanTree(HT,w,n);fp1=fopen("CodeFile、txt","r");fp2=fopen("TextFile、txt","w");while(uncodef(fp1,fp2,HT,2*n-1));printf("\n");printf("\n解码已写入文件TextFile、txt 中、\n");fclose(fp1);fclose(fp2);}void visite(Huff HT,int i,int flag,int rear)//通过递归调用visite()函数,得到各个字母的编码,存储于全局变量code[][]中{intj=0,k=0;if(flag==0){ stack[rear]=0;rear++;}elseif(flag==1){stack[rear]=1;rear++;}if(HT[i]、lchild==0){for(j=0;j<rear;j++){code[i][j]=stack[j];}code[ i][j]=#;rear--;return;}visite(HT,HT[i]、lchild,0,rear);visite(HT,HT[i]、rchild,1,rear);k=rear;for(j=0;j<k;j++){code[i][j]=stack[j ];}code[i][j]=#;rear--;return;}void translatef(char*scource,char *save,int n)//读取文件中的字母序列,并根据code[][]将其转换成01序列输出{FILE *fp1,*fp2;char p= ;int i=0,j=0,k=0;fp1=fopen(scource,"r");fp2=fopen(save,"w");p= fgetc(fp1);printf("\n得到的编码为:\n");while(p!=EOF){for(i=0;i<=n;i++){if(c[i]==p){for(j =0;j<N&&code[i][j]!=#;j++){fputc(code[i][j],fp2);putchar( code[i][j]);k++;if(k>=50){k=0;putchar(\n);}}}}p=fgetc(fp1 );}fclose(fp1);fclose(fp2);}bool uncodef(FILE *fp1,FILE *fp2,Huff HT,int n)//通过对树的访问,把文件中01序列转换成一个字母输出。
C++实现哈夫曼编码完整代码

C++实现哈夫曼编码完整代码#include <iostream>#include <queue>#include <vector>#include <map>#include <string>using namespace std;class Node {public:char c; //表示字符int frequency; //表示该字符出现的次数或频率Node *left;Node *right;Node(char _c, int f, Node *l = NULL, Node *r = NULL):c(_c), frequency(f), left(l), right(r) { }bool operator<(const Node &node) const { //重载<运算法以至于在加入优先队列的时候决定如何处理结点位置return frequency > node.frequency;}};void initNode(priority_queue<Node> &q, int nodeNum) {char c;int frequency;for (int i = 0; i < nodeNum; i++) {cout << "输入字符和结点出现的次数: ";cin >> c >> frequency;Node node(c, frequency);q.push(node);}}void showNode(priority_queue<Node> q) {while (!q.empty()) {Node node = q.top(); q.pop();cout << node.c << ", " << node.frequency << endl;}}//构造哈夫曼树void huffmanTree(priority_queue<Node> &q) {while (q.size() != 1) {Node *left = new Node(q.top()); q.pop();Node *right = new Node(q.top()); q.pop();Node node('R', left->frequency + right->frequency, left, right);q.push(node);}}// 打印哈夫曼编码void huffmanCode(Node *root, string &prefix, map<char, string> &result) { string m_prefix = prefix;if (root->left == NULL)return;//处理左子树prefix += "0";//如果是叶子结点则输出,否则递归打印左子树if (root->left->left == NULL)result[root->left->c] = prefix;//cout << root->left->c << ": " << prefix << endl;elsehuffmanCode(root->left, prefix, result);//还原原来的路径,回溯prefix = m_prefix;//处理右子树prefix += "1";//如果是叶子结点,则输出, 否则递归打印右子树if (root->right->right == NULL)result[root->right->c] = prefix;//cout << root->right->c << ": " << prefix << endl;elsehuffmanCode(root->right, prefix, result);}void testResult(map<char, string> result) {//迭代map容器map<char, string>::const_iterator it = result.begin(); while (it != result.end()) {cout << it->first << ": " << it->second << endl;++it;}}int main() {priority_queue<Node> q;int nodeNum;//初始化字符信息cout << "请输入结点个数: ";cin >> nodeNum;initNode(q, nodeNum);//showNode(q);//构造哈夫曼树huffmanTree(q);//构造哈夫曼编码Node root = q.top();string prefix = "";map<char, string> result;huffmanCode(&root, prefix, result);//检验结果是否正确testResult(result);return 0;}。
哈夫曼编码-数据结构-C程序

数据结构课程设计一、目的《数据结构》是一门实践性较强的软件基础课程,为了学好这门课程,必须在掌握理论知识的同时,加强上机实践。
本课程设计的目的就是要达到理论与实际应用相结合,使同学们能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养基本的、良好的程序设计技能。
二、要求通过这次设计,要求在数据结构析逻辑特性和物理表示,数据结构的选择的应用、算法的设计及其实现等方面中深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
三、内容2.哈夫曼编码/译码器【问题描述】设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。
【基本要求】(1)初始化:键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;(2)编码:利用建好的哈夫曼树生成哈夫曼编码;(3)输出编码;(4)设字符集及频度如下表:字符空格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【选做内容】(1)译码功能;(2)显示哈夫曼树;(3)界面设计的优化。
哈夫曼编写编译码一、问题描述利用哈夫曼编码进行通信可以大大提高信道利用率,这要求在发送端通过一个编码系统对待传输预先编码,在接收端将传来的数据进行译码。
对于双工通道,每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼码的编/译码系统。
二、概要设计1.哈夫曼树的定义:在一棵二叉树中,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。
2.哈夫曼树的构造:假设有N个权值,则构造出的哈夫曼树有N个叶子结点。
N个权值分别设为W1,W2,……….Wn,则哈夫曼树的构造规则为:(1)将W1,W2,……….Wn看成有N棵树的森林;(2)在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左,右子树,且新树的根结点为其左,右子树结点权值之和;(3)从森林中删除选取取的两面三刀棵树,并将新树加入森林;(4)重复(2)(3)步,直到森林中只剩一棵树为止,该树即为我们所求得的哈夫曼树。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1)内容:利用 Huffman 编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在接收端进行解码。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/解码系统。
2)要求:一个完整的huffman编解码系统应该具有以下功能:初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman 树,并将它存入hfmTree 中。
编码(Encoding)。
利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree 中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
解码(Decoding)。
利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
打印代码文件(Print)。
将文件CodeFile以紧凑的格式显示在终端上,每行 50 个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
打印Huffman树(Tree Printing)。
将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。
3) 测试数据:用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:“THIS PROGRAM IS MY FAVORITE”。
完整代码如下:#include<stdio.h>#include<iostream>#include<string>#define N 100int *w;char *c,stack[N],code[N][N];int s1,s2;typedef struct HuffmanTree{int weight;int parent;int lchild;int rchild;}HuffmanTree,*Huff;void menu(void);void Select(struct HuffmanTree HT[],int i);void HuffmanTree(Huff &HT,int *w,int n);void visite(Huff HT,int i,int flag,int rear);void translatef(char *scource,char *save,int n);bool uncodef(FILE *fp1,FILE *fp2,Huff HT,int n);int inputHuff();void screanio(int n);void fileio(int n);int initHuff();void Print_tree(int n,Huff HT);void Convert_tree(Huff HT,unsigned char T[100][100],int tt[100][100],int s,int *i,int j);void decoding(int n);void coding(int n);void main(){int n=0;menu();Huff HT;char state;do{std::cout<<"input:\n";std::cin>>state;fflush(stdin); //读取状态switch(state){case'I':n=inputHuff();HuffmanTree(HT,w,n);std::cout<<"\nHuffmanTree 初始化完毕\n";break;case'C':coding(n);break;case'D':decoding(n);break;case'P':Print_tree(n,HT);break;case'Q':break;}}while(state!='Q');}void menu() //显示菜单函数{std::cout<<"===========HuffmanCoding===========\n";std::cout<<"input \t\t do\n";std::cout<<"I \t\tInit_HUffTree\n"; //初始化huffmantreestd::cout<<"C \t\tCoding\n"; //对ToBeTran.txt文件中的字符进行编码到CodeFile.txt中std::cout<<"D \t\tUnCoding\n"; //对CodeFile.txt中的01序列进行解码到TextFile.txtstd::cout<<"P \t\tPrintTree\n"; //打印哈夫曼树std::cout<<"Q \t\tquit\n";std::cout<<"请初始化哈夫曼树再执行后面的操作\n";}int inputHuff() //输入各个字母及其权值{int i=1,n=0;int ww[28];char cc[28];while(1){std::cout<<"input the letter(input '#' to stop):";cc[i]=std::cin.get();fflush(stdin);if(cc[i]=='#')break;std::cout<<"input the weight:";std::cin>>ww[i];fflush(stdin);n++;i++;}w=(int *)malloc(sizeof(int)*(n+1));c=(char *)malloc(sizeof(char)*(n+1));for(i=0;i<n+1;i++){w[i]=ww[i];c[i]=cc[i];}return n;}void HuffmanTree(Huff &HT,int *w,int n) //初始化哈夫曼树{int m,i;m=n*2-1;HT=(struct HuffmanTree *)malloc(sizeof(struct HuffmanTree)*(m+1));HT[0].lchild=0;HT[0].parent=0;HT[0].rchild=0;HT[0].weight=0;for(i=1;i<m;i++){HT[i].weight=i<=n?w[i]:0;HT[i].lchild=HT[i].rchild=HT[i].parent=0;}for(i=n+1;i<=m;i++){Select(HT,i);HT[i].lchild=s1;HT[i].rchild=s2;HT[i].weight=HT[s1].weight+HT[s2].weight;HT[s1].parent=HT[s2].parent=i;}}void Select(struct HuffmanTree HT[],int i) //在HT[1..i-1]中选择parent为0且weight为最小的两个结点{int j;for(j=1;j<i;j++){if(HT[j].parent ==0){s1=j;s2=j;goto flag;}}flag: for(j=s1+1;j<i;j++){if(HT[j].parent==0){if(HT[s1].weight >=HT[j].weight){s2=s1;s1=j;}if(HT[s2].weight>HT[j].weight&&j!=s1)s2=j;if(s1==s2)s2=j;}}}void Print_tree(int n,Huff HT) //以凹入法的形式打印树{unsigned char T[100][100];int tt[100][100];int i,j,m=0;FILE *fp;Convert_tree(HT,T,tt,0,&m,2*n-1); //将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中if((fp=fopen("treeprint.txt","wb+"))==NULL)printf("Open file treeprint.txt error!\n");printf("\n以凹凸表形式打印已建好的赫夫曼树:\n");for(i=1;i<=2*n-1;i++){for (j=0;T[i][j]!=0;j++){if(T[i][j]==' ') {printf(" ");fputc(T[i][j],fp);}else{printf("%d",tt[i][j]);fprintf(fp,"%d\n\n\n",tt[i][j]);} }printf("\n");}fclose(fp);printf("\n此字符形式的哈夫曼树已写入文件treeprint.txt中.\n\n");printf("\n文件treeprint.txt的打开方式要为写字板,若打开方式为记事本,则无法显示凹凸表的形式\n");}void Convert_tree(Huff HT,unsigned char T[100][100],int tt[100][100],int s,int *i,int j) //将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中{int k,l;l=++(*i);for(k=0;k<s;k++)T[l][k]=' ';T[l][k]='#';tt[l][k]=HT[j].weight;if(HT[j].lchild)Convert_tree(HT,T,tt,s+1,i,HT[j].lchild);if(HT[j].rchild)Convert_tree(HT,T,tt,s+1,i,HT[j].rchild);T[l][++k]='\0';}void coding(int n) //对文件ToBeTran.txt编码到CodeFile.txt{FILE *fp1;Huff HT;HuffmanTree(HT,w,n);visite(HT,2*n-1,2,0);fflush(stdin);translatef("ToBeTran.txt","CodeFile.txt",n);fp1=fopen("CodeFile.txt","r");printf("\n编码已写入文件treeprint.txt中.\n");fclose(fp1);}void decoding(int n) //对CodeFile.txt中的01序列进行解码到TextFile.txt{FILE *fp1,*fp2;Huff HT;HuffmanTree(HT,w,n);fp1=fopen("CodeFile.txt","r");fp2=fopen("TextFile.txt","w");while(uncodef(fp1,fp2,HT,2*n-1));printf("\n");printf("\n解码已写入文件TextFile.txt中.\n");fclose(fp1);fclose(fp2);}void visite(Huff HT,int i,int flag,int rear)//通过递归调用visite()函数,得到各个字母的编码,存储于全局变量code[][]中{int j=0,k=0;if(flag==0){stack[rear]='0';rear++;}else if(flag==1){stack[rear]='1';rear++;}if(HT[i].lchild==0){for(j=0;j<rear;j++){code[i][j]=stack[j];}code[i][j]='#';rear--;return;}visite(HT,HT[i].lchild,0,rear);visite(HT,HT[i].rchild,1,rear);k=rear;for(j=0;j<k;j++){code[i][j]=stack[j];}code[i][j]='#';rear--;return;}void translatef(char *scource,char *save,int n)//读取文件中的字母序列,并根据code[][]将其转换成01序列输出{FILE *fp1,*fp2;char p=' ';int i=0,j=0,k=0;fp1=fopen(scource,"r");fp2=fopen(save,"w");p=fgetc(fp1);printf("\n得到的编码为:\n");while(p!=EOF){for(i=0;i<=n;i++){if(c[i]==p){for(j=0;j<N&&code[i][j]!='#';j++){fputc(code[i][j],fp2);putchar(code[i][j]);k++;if(k>=50){k=0;putchar('\n');}}}}p=fgetc(fp1);}fclose(fp1);fclose(fp2);}bool uncodef(FILE *fp1,FILE *fp2,Huff HT,int n)//通过对树的访问,把文件中01序列转换成一个字母输出。