什么是哈夫曼树
当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”。
在构建哈弗曼树时,要使树的带权路径长度最小,只需要遵循一个原则,那就是:权重越大的结点离树根越近。在图 1 中,因为结点 a 的权值最大,所以理应直接作为根结点的孩子结点。
#include<stdio.h> #include<stdlib.h> #include<conio.h> #include<string.h> #include<limits.h> typedef struct{ unsigned int weight; unsigned int parent,lchild,rchild; }htnode,*huffmantree; // 赫夫曼树的结构类型 typedef char **huffmancode; int min(huffmantree t, int i){ int j,flag; unsigned int k=UINT_MAX; for(j=1;j<=i;j++){ if(t[j].weight<k&&t[j].parent==0){ k=t[j].weight; flag=j; } } t[flag].parent=1; return flag; } void select(huffmantree t,int i,int &s1,int &s2){ int j; s1=min(t,i); s2=min(t,i); if(s1>s2){ j=s1; s1=s2; s2=j; } } void huffmancoding(huffmantree &ht,huffmancode &hc,int *w,int n){ int m,i,s1,s2,start; unsigned int c,f; huffmantree p; char *cd=NULL; m=2*n-1; ht=(huffmantree)malloc((m+1)*sizeof(htnode)); // m+1表示0号单元不用 for(p=ht+1,i=1;i<=n;i++,p++){ p->weight=w[i-1]; p->parent=0; p->lchild=0; p->rchild=0; } for(;i<=m;i++,p++){ p->parent=0; } for(i=n+1;i<=m;i++){ //建立赫夫曼树 select(ht,i-1,s1,s2); ht[s1].parent=ht[s2].parent=i; ht[i].lchild=s1; ht[i].rchild=s2; ht[i].weight=ht[s1].weight+ht[s2].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(c=i,f=ht[i].parent;f!=0;c=f,f=ht[f].parent){ // 一直循环知道最后一个没有双亲的结点,用f来寻找父母往上走 if(ht[f].lchild==c) cd[--start]=‘0‘; else cd[--start]=‘1‘; //这里分支语句用来判断在左还是右,编码0和1 } //n-1位置已经存放了‘/0‘,所以用--start,从n-2存放0,1编码 hc[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(hc[i],&cd[start]); } free(cd); } int main(){ huffmantree ht=NULL; // 二级指针 huffmancode hc; int *w,n,i; printf("Please input the number of all the node digit:"); scanf("%d",&n); w=(int *)malloc(n*sizeof(int)); printf("Please input the %d node digits:\n",n); for(i=0;i<n;i++){ scanf("%d",w+i); } huffmancoding(ht,hc,w,n); for(i=1;i<=n;i++){ puts(hc[i]);} getch(); }
原文地址:https://www.cnblogs.com/xiaoqiz/p/10847191.html
时间: 2024-11-05 14:58:24