(数据结构) 哈夫曼树的编码和解码简单的实现

    技术2025-04-15  10

    输入一段英文原文,构造哈夫曼树,生成对应的编码表,输出原文对应的编码,或者是根据已经生成的编码表,输入一段二进制数编码,得到对应的字符原文。

    #include<stdio.h> #include<iostream> #include<conio.h> #include<string.h> #include<stdlib.h> using namespace std; //哈夫曼树的存储表示 typedef struct{ int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char **HuffmanCode; //存储两个最小的权值 typedef struct{ int s1; int s2; }MinCode; void print1(HuffmanTree &HT,int m){ printf("HT List:\n"); printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n"); for(int i=1;i<=m;i++){ printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); } system("pause"); } //void fun(char* str){ // for(int i=0,ch='\0';ch!='\n';++i){ // ch=getchar(); // if(i>=100){ // continue; // } // if(ch=='\n' || i==100-1){ // str[i] = '\0'; // continue; // } // str[i] = ch; // } //} //查找最小的两个权值 MinCode Select(HuffmanTree HT,int n){ int k=1,s1,s2; MinCode code; int min=666666; for(k=1;k<=n;k++){ // cout<<"aaaaaaaaaa"<<endl; if(HT[k].parent==0&&HT[k].weight<min){ min=HT[k].weight; s1=k; } } int smin=666666; for(k=1;k<=n;k++){ // cout<<"aaaaaaaaaa"<<endl; if(HT[k].parent==0&&(HT[k].weight<smin)&&(k!=s1)){ smin=HT[k].weight; s2=k; } } code.s1=s1; code.s2=s2; return code; } //构造哈夫曼树 HuffmanCode CreateHuffmanTree(HuffmanTree &HT,HuffmanCode &HC,int n,int *w){ int i,s1=0,s2=0; char a; MinCode Min; HuffmanTree p; if(n<=1) { return 0; } int m=2*n-1; //printf("%d",m); HT=new HTNode[m+1];//零号单元未用,所以需要分配m+1个单元,HT[m]表示根节点 //初始化 for(p=HT,i=0;i<=n;i++,p++,w++){ p->weight=*w; p->parent=0; p->lchild=0; p->rchild=0; } //----------- 初始化结束------------- //进行删除,合并 构造新的哈夫曼树 for(i=n+1;i<=m;i++){ 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("是否打印哈夫曼树?y or n\n"); scanf("%s",&a); if(a=='y'){ print1(HT,m); }else if(a!='y') { printf("将返回主界面\n"); } // //打印哈夫曼树 // printf("HT List:\n"); // printf("Number\t\tweight\t\t\tparent\t\tlchild\t\trchild\n"); // for(i=1;i<=m;i++){ // printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); // } //从叶子到根逆向球每个字符的哈夫曼编码,存储在编码表HC中 int start,c,f; char *cd; HC=new char *[n+1]; cd=new char[n]; cd[n-1]='\0'; for(int i=1;i<=n;i++){ start=n-1; c=i;f=HT[i].parent; while(f!=0){ --start; if(HT[f].lchild==c){ cd[start]='0'; }else{ cd[start]='1'; } c=f;f=HT[f].parent; } HC[i]=new char[n-start]; strcpy(HC[i],&cd[start]); } delete cd; return HC; } //哈夫曼译码,对输入的10组合进行译码 void HuffmanTranslateCoding(HuffmanTree HT,int n,char *ch,char *N){ int m=2*n-1; int i,j=0; while (ch[j]!='\0'){ i=m; while(0!=HT[i].lchild && 0!=HT[i].rchild){ if('0'==ch[j]){ i=HT[i].lchild; }else{ i=HT[i].rchild; } ++j; } printf("%c",N[i-1]); } printf("\n"); } int main(){ int n,i,m; int *w=NULL; int chioce; HuffmanCode HC; HuffmanTree HT=NULL; char N[100]; char tran[100]; while(1){ system("cls"); printf("\t\t######################################\n"); printf("\t\t# 1.初始化 #\n"); printf("\t\t# 2.解码 #\n"); printf("\t\t# 3.打印哈夫曼树 #\n"); printf("\t\t# 4.打印译码表 #\n"); printf("\t\t# 0.退出 #\n"); printf("\t\t# (使用前必须初始化!!!) #\n"); printf("\t\t######################################\n"); printf("输入选择: "); scanf("%d",&chioce); if(chioce==0) break; switch(chioce){ case 1: { printf("\t\t输入字符串:\n"); scanf("%s",&N); //fflush(stdin); n=strlen(N); m=2*n-1; w=(int *)malloc((n+1)*sizeof(int *)); w[0]=0; printf("\t\t输入权值\n"); for(i=1;i<=n;i++){ printf("w[%d]=",i); scanf("%d",&w[i]); } //fflush(stdin); CreateHuffmanTree(HT,HC,n,w); //fflush(stdin); system("pause"); break; } case 2: { //译码过程 printf("Input HuffmanTranslateCoding:\n"); scanf("%s",&tran); //打印1,0组合对应字符 HuffmanTranslateCoding(HT,n,tran,N); system("pause"); break; } case 3:print1(HT,2*n-1); break; case 4: { printf("HuffmanCode:\n"); printf("Number\t\tWeight\t\tCode\n"); for(i=1;i<=n;i++){ printf("%c\t\t%d\t\t%s\n",N[i-1],w[i],HC[i]); } system("pause"); break; } default : printf("\t\t没有此选项\n"); break; } } return 0; }

     

    Processed: 0.010, SQL: 9