哈夫曼编码的练习

注释仅仅是个人意见,随着理解的加深会越来越接近正确的

/* 整个哈夫曼编码实际上就是设定一个数组,树有n个节点的话就设立大小为2*n-1 的数组, 因为在最理想情况下最多仅有最小的两个元素处于以编码后的哈夫曼树的最低端,这样的 话会用去n-1个空间来存储编码后的parent。因此哈夫曼编码实际上就是把树存为一元数组 打表后查找的过程(个人思考) */ /* l存储树的树的节点树 n=2*l—1在数组的l+1到n位置存储编码后的每个非终端节点(非原树上的节点) */ #include<stdio.h> #include<stdlib.h> #include<string.h> struct HtNode { unsigned int weight; unsigned int parent,lchild,rchild; }HtNode,*Huffmantree; struct HtNode *Ht,*p; typedef char **Huffmancode; //二维数组,实际上是存每个节点的编码 Huffmancode Hc; char *cd; int n,a1,a2,l; int i,w=0,start,f,c; int select() //我勒个去,怎么才发现你丫是个穷举法选出来的最小值,丫真猥琐 { int k=1,j,flag=0; //有parent的意思就是已经被编码了 while((Ht+k)->parent!=0) k++; //找啊找的,一直找到还没被编码的第一个元素,以它为起点找 for(j=k+1;j<=n;j++,flag=0) //每次循环都要把flag置为0 { if((Ht+j)->parent!=0) flag=1; //如果已经编码的话,k值不变,j继续自加循环 if((Ht+j)->weight==0) flag=1; //在1到l的阶段存储原树的节点,l+1到n的阶段存储哈夫曼树的非终端节点 //则weight为0的话肯定是l+1到n的阶段中的没有存值的节点 if(!flag) //如果未出现上述两种情况且位置k所存节点的weight不是最小的, //那么k的值就要变化,并且从新的k开始再循环 { if(((Ht+j)->weight)<((Ht+k)->weight)) k=j; } } return k; } int main() { printf("哈夫曼树的建立/n"); printf("请输入叶子(权值)的数目:/n"); scanf("%d",&l); while(l<1) { printf("输入错误,请重新输入权值 /n"); scanf("%d",&l); } if(l==1) printf("仅有一个元素,无需构造哈夫曼树"); else { n=2*l-1; //Huffmantree Ht; Ht=(struct HtNode *)malloc(sizeof(struct HtNode)*(n+1)); //Huffmantree p; printf("输入元素权值/n"); for(i=1,p=Ht+1;i<=l;i++,p++) { scanf("%d",&w); while(w<=0) { printf("输入错啦,请重新输入/n"); scanf("%d",&w); } p->weight=w; p->lchild=0; p->rchild=0; p->parent=0; } //输入树的各个节点的值 for(i=l+1;i<=n;i++,p++) { p->weight=0; p->lchild=0; p->rchild=0; //不知道为什么没这句 p->parent=0; } //初始化准备存非终端节点的值 for(i=l+1;i<=n;i++) //这个<=号很重要,事实上本算法中都是<=的,从1开始的嘛 { a1=select(); (Ht+a1)->parent=i; a2=select(); (Ht+a2)->parent=i; (Ht+i)->lchild=a1; (Ht+i)->rchild=a2; (Ht+i)->weight=(Ht+a1)->weight+(Ht+a2)->weight; } //进行存值处理,所谓建立这个树 //下面的代码完成编码的任务 Hc=(Huffmancode)malloc((l+1)*sizeof(char *));//二维数组 cd=(char *)malloc(sizeof(char)*l); cd[l-1]='/0'; //每个数组的最后一个代表结束 for(i=1;i<=l;i++) { start=l-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(sizeof(char)*(l-start)); strcpy(*(Hc+i),(cd+start)); } printf("对应编码为/n"); for(i=1;i<=l;i++) { printf("%s ",*(Hc+i)); if(i%5==0) printf("/n"); } } system("pause"); } /* 4 12 32 2341 321 */

你可能感兴趣的:(算法,struct,System,存储,任务,终端)