- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- typedef struct{
- unsigned int weight; //权值
- unsigned int parent,lchild,rchild; //父节点,左子树,右子树
- }HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树
- typedef char ** HuffmanCode; //动态分配数组存储赫夫曼编码表
- unsigned int min1,min2;
- void Select(HuffmanTree &HT,int i,int &s1,int &s2)
- {
- min1=min2=32767;
- s1=s2=0;
- int j;
- for(j=1;j<=i;j++)
- {
- if(HT[j].weight<min1&&!HT[j].parent)
- {
- min2=min1;
- s2=s1;
- min1=HT[j].weight;
- s1=j;
- }
- else if(HT[j].weight<min2&&!HT[j].parent)
- {
- min2=HT[j].weight;
- s2=j;
- }
- }
- }
- void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){
- //w存放n个字符的权值,构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
- int m;//m表示赫夫曼树总共结点
- int i;
- int s1=0;
- int s2=0;
- HuffmanTree p;
- char *cd;
- unsigned int start,c,f;
- if(n<=1)
- return;
- m = 2*n -1 ; //节点数
- HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode)); //分配存储空间,0号单元未用
- for(p = HT+1,i=1;i<=n;++i,++p){
- p->weight = w[i];
- p->parent = 0;
- p->lchild = 0;
- p->rchild = 0;
- }
- for(i=n+1;i<=m;++i,++p){
- p->weight = 0;
- p->parent = 0;
- p->lchild = 0;
- p->rchild = 0;
- }
- for(i=n+1;i<=m;++i){ //建赫夫曼树
- //在HT[1...i-1]选择parent为0且weight最小的两个结点,其序号分别为是s1和s2
- Select(HT,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;
- }
- for(i=1;i<=m;i++)
- printf("%d,%d,%d\n",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
- //从叶子到根逆向求每个字符的赫夫曼编码
- HC = (HuffmanCode)malloc((n+1)*sizeof(char *)); //分配n个字符编码的头指针向量
- cd = (char *)malloc(n*sizeof(char)); //分配求编码的工作空间
- cd[n-1] ='\0'; //编码结束符
- for(i=1;i<=n;++i){
- 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);
- }
- void main(){
- int n;
- int NT[100];
- int i;
- HuffmanTree HT;
- HuffmanCode HC;
- printf("请输入你的赫夫曼树的叶子结点个数:\n\n");
- scanf("%d",&n);
- for(i=1;i<=n;i++)
- {
- printf("输入第 %d 个数字的权重",i);
- scanf("%d",&NT[i]);
- }
- HuffmanCoding(HT,HC,NT,n);
- printf("赫夫曼树编码如下:\n\n");
- for(i=1;i<=n;i++)
- {
- printf("%d :%s\n",HC[i]);
- }
- printf("\n\n");
- }
By Mr.Z