C语言:哈夫曼树的编码与译码

来源:互联网 发布:oracle数据库下载安装 编辑:程序博客网 时间:2024/05/22 00:14
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>#define N 100typedef struct {int weight;int parent, lchild, rchild;}hafuman;typedef struct {char data[N]; //字符数据char copy[N][10*N];//编码}bianma;void display(); int input(int w[], bianma *bm);void creat_hafuman(hafuman ht[], int w[], int n);void select(hafuman ht[], int m, int *s1,  int *s2);void encoding(hafuman ht[], bianma *bm, int n);void coding(bianma *bm, int n);//译码void coding_2(hafuman ht[], bianma *bm, int n);//译码void output(bianma *bm, int n);int i, j, k;void display(){printf("\n\n\n");printf("\t\t\t1.输出编码\n\n");printf("\t\t\t2.进行译码\n\n");printf("\t\t\t3.退出\n\n");printf("\t\t请选择(1~~3):  ");}int input(int w[], bianma *bm){int n=0;printf("\n请输入要进行编码的文章或句子(#结束)\n");while(1){bm->data[n]=getchar();if(bm->data[n]=='#')break;n++;}for(i=0; i<n; i++){w[i]=1;for(j=i+1; j<n; ){if( bm->data[i] == bm->data[j] ){w[i]++;for(k=j; k<n; k++){ bm->data[k]=bm->data[k+1];}n--; //覆盖完之后n--;}elsej++;}}printf("\n\n");printf("不同的字符\n");for(i=0; i<n; i++){printf("%c", bm->data[i]);}return n;}void creat_hafuman(hafuman ht[], int w[], int n){int s1, s2;int t;for(t=1; t<=n; t++){ht[t].weight=w[t-1];ht[t].parent=0;ht[t].lchild=0;ht[t].rchild=0;}for(t=n+1; t<=2*n-1; t++){ht[t].weight=0;ht[t].parent=0;ht[t].lchild=0;ht[t].rchild=0;}for(t=n+1; t<=2*n-1; t++){select(ht, t-1, &s1, &s2);//前i-1中选双亲为0, 权值最小ht[t].weight=ht[s1].weight + ht[s2].weight;ht[t].lchild=s1, ht[t].rchild=s2;ht[s1].parent=t, ht[s2].parent=t;}}void select(hafuman ht[], int m, int *s1,  int *s2){int min1, min2, a, b;i=1;while( ht[i].parent != 0){i++;}min1=ht[i].weight; a=i;for(j=i+1; j<=m; j++){if(min1 > ht[j].weight && ht[j].parent==0){min1=ht[j].weight;a=j;}}i=1;while( ht[i].parent != 0 || a==i ){i++;}min2=ht[i].weight;b=i;for(j=i+1; j<=m; j++){if(j==a)continue;if(min2 > ht[j].weight && ht[j].parent==0){min2=ht[j].weight;b=j;}}*s1=a; *s2=b;}void encoding(hafuman ht[], bianma *bm, int n)//编码, *copy[]为复制编码{int start, c, p;char *ch;ch=(char *)malloc( n*sizeof(char) );ch[n-1]='\0';for(i=1; i<=n; i++)//n个叶子节点{start=n-1;    c=i, p=ht[i].parent; //p为parent, c为childwhile(p!=0){start--;if(ht[p].lchild==c)ch[start]='0';elsech[start]='1';c=p; p=ht[p].parent;//printf("\n123\n");}    strcpy( bm->copy[i-1], &ch[start] );//printf("\n%s\n", bm->copy[i-1]);}free(ch);}void coding_2(hafuman ht[], bianma *bm, int n)//译码{char s[10*N];int p;printf("\n请输入要译码的字符\n");fflush(stdin);gets(s);printf("\n译码\n\n");p=2*n-1;for(i=0; s[i] != '\0'; i++){if(s[i]=='0')p=ht[p].lchild;elseif(s[i]=='1')p=ht[p].rchild;if(ht[p].lchild == 0 && ht[p].rchild == 0){ printf("%c", bm->data[p-1]);//p: 1~~2*n-1, bbm->data[0~~n-1]p=2*n-1;continue;}}puts("\n\n");}void output(bianma *bm, int n){printf("\n");for(i=0; i<n; i++){printf("%c\t", bm->data[i] );printf("%s\n", bm->copy[i]);}}void main(){hafuman ht[N];bianma *bm;int w[N];int n, m;bm=(bianma *)malloc( sizeof(bianma) );n=input(w, bm);printf("\n\n不同字符总数: %d\n\n", n);    creat_hafuman(ht, w, n); encoding(ht, bm, n); getch();    system("cls");loop:display();scanf("%d",  &m);switch(m){case 1:         output(bm, n);printf("\n\n请按任意键继续");getch();system("cls");goto loop;break;case 2://coding(bm, n);//译码coding_2(ht, bm, n);//译码printf("\n\n请按任意键继续");getch();system("cls");goto loop;break;case 3:break;default:system("cls");  goto loop;}} 

0 0
原创粉丝点击