#include "stdio.h" #define N 8 typedef struct { unsigned int weight;//节点权重 unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char ** HuffmanCode; int useable[N*2]={0}; //选择最小的两个权值,已经选过了的就不能选了 void Select(HuffmanTree HT,int n,int *s1,int *s2) { unsigned int max=0xffffffff; HuffmanTree p; int index; int i; for( p=HT,p++,i = 1; i <= n; i++,p++) { if( p->weight < max && 0==useable[i] ) { max=p->weight; *s1=i; } } useable[*s1]=1; max=0xffffffff; for(p=HT,p++, i = 1; i <= n; i++,++p) { if( p->weight < max && 0==useable[i] ) { max=p->weight; *s2=i; } } useable[*s2]=1; } //w存放的是各个字符的权值 void HuffmanCoding(HuffmanTree* HT,HuffmanCode * HC,int *w,int n) { int i,j,m; int s1,s2; int start,f; char * cd; HuffmanTree p ; if( n < 1 ) { return; } m= 2*n-1; *HT=(HuffmanTree)malloc( (m+1)*sizeof(HTNode)); memset(*HT,0,(m+1)*sizeof(HTNode)); //将权值付给各个叶子节点 for(p=*HT,i=1,p++;i<=n;++i,++p,++w) { p->weight=*w; printf("%d=%d\n",i,p->weight); } p=*HT; //建立赫夫曼树 for(i=n+1;i<=m;i++) { Select(p,i-1,&s1,&s2); (*HT)[s1].parent=i; (*HT)[s2].parent=i; (*HT)[i].weight=(*HT)[s1].weight + (*HT)[s2].weight; (*HT)[i].lchild=s1; (*HT)[i].rchild=s2; if(s1>n) { (*HT)[i].lchild=s2; (*HT)[i].rchild=s1; } printf("s1=%d,s2=%d i=%d (*HT)[i].weight=%d\n",s1,s2,i,(*HT)[i].weight); } // for(p=*HT,i=1;i<=m;++i,++p) { printf("%d=%d\n",i,p->weight); } *HC=(HuffmanCode)malloc( (n+1)*sizeof(char*) ); cd=(char *)malloc(n*sizeof(char)); cd[n-1]='\0'; //开始从叶子结点编码 for(i=1;i<=n;i++) { start=n-1; for(j=i,f=(*HT)[i].parent; f!=0; j=f,f=(*HT)[f].parent) { if( (*HT)[f].lchild == j) { cd[--start]='0'; } else { cd[--start]='1'; } } (*HC)[i]=(char *)malloc( (n-start)*sizeof(char) ); printf("%s\n",&cd[start]); strcpy((*HC)[i],&cd[start]); } free(cd); } void showcode(HuffmanTree HT,HuffmanCode HC,int n) { int i; HuffmanTree p=HT; p++; for(i=1;i<=n;i++) { printf("i=%d %d=%s\n",i,p->weight,HC[i]); p++; } } void main() { int W[N]={5,29,7,8,14,23,3,11}; HuffmanTree HT; HuffmanCode HC; HuffmanCoding(&HT,&HC,W,8); showcode( HT, HC, 8); }