求哈夫曼树的编码
Posted eternity–twinkle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求哈夫曼树的编码相关的知识,希望对你有一定的参考价值。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define N 20 5 #define M 2*N-1 6 typedef struct 7 //哈夫曼树的类型定义 8 { 9 int weight; 10 int parent; 11 int LChild; 12 int RChild; 13 }HTNode,HuffmanTree[M+1]; 14 typedef char *HuffmanCode[N+1]; 15 void CrtHuffmanTree(HuffmanTree ht,int w[],int n)//构造哈夫曼树ht[M+1],w[]存放n个权值 16 17 { 18 int i,k,Lnode,Rnode,Min1,Min2,max=0; 19 int m=2*n-1; 20 for(i=1;i<=n;i++) //叶子结点初始化 21 { 22 ht[i].weight=w[i]; 23 ht[i].parent=0; 24 ht[i].LChild=0; 25 ht[i].RChild=0; 26 } 27 /[i]={ w[i],0,0,0}; 28 for(i=n+1;i<=m;i++) //非叶子结点初始化 29 /[i]={0,0,0,0}; 30 { 31 ht[i].weight=0; 32 ht[i].parent=0; 33 ht[i].LChild=0; 34 ht[i].RChild=0; 35 } 36 37 38 /* 39 40 for(i=1;i<=m;i++) 41 { 42 printf(" %d,",w[i]); 43 } 44 printf(" %n"); 45 for(i=1;i<=m;i++) 46 { 47 printf(" %d,",ht[i].weight); 48 } 49 printf(" %d\\n",max); 50 51 */ 52 53 54 55 for(i=n+1;i<=m;i++)//建立哈夫曼树 56 { 57 Min1=Min2=10000; 58 Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置 59 for(k=1;k<i;k++)//只在尚未构造二叉树的结点中查找最小的两个结点 60 { 61 if(ht[k].parent==0) 62 { 63 if(ht[k].weight<Min1)//查找当前最小值 64 { 65 Min2=Min1; 66 Rnode=Lnode; 67 Min1=ht[k].weight; 68 Lnode=k; 69 } 70 else 71 if(k!=Lnode&&ht[k].weight<Min2)//查找当前第二最小值 72 { 73 Min2=ht[k].weight; 74 Rnode=k; 75 } 76 } 77 } 78 ht[i].weight=Min1+Min2; 79 ht[i].LChild=Lnode;ht[i].RChild=Rnode; 80 ht[Lnode].parent=i;ht[Rnode].parent=i; 81 } 82 printf("\\n哈夫曼树的终态\\n序号\\tWeight\\tParent\\tLChild\\tRChild\\n"); 83 for(i=1;i<=m;i++)//测试代码 84 { 85 printf("%d",i); 86 printf(" %d",ht[i].weight); 87 printf(" %d",ht[i].parent); 88 printf(" %d",ht[i].LChild); 89 printf(" %d",ht[i].RChild); 90 printf("\\n"); 91 } 92 printf("\\n"); 93 94 95 } 96 void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n) 97 //从叶子结点到根,逆求每个叶子结点对应的哈夫曼编码,左0右1 98 { 99 char *cd; 100 int i,j,c,p,start; 101 cd=(char *)malloc(n*sizeof(char)); 102 cd[n-1]=\'\\0\'; 103 for(i=1;i<=n;i++) 104 { 105 start=n-1; 106 c=i;p=ht[i].parent; //寻找该叶子结点的父母 107 while(p!=0) 108 { 109 --start; 110 if(ht[p].LChild==c) 111 cd[start]=\'0\';//判断是左边还是右边 112 else 113 cd[start]=\'1\'; 114 c=p;p=ht[p].parent;//继续向上倒推 115 } 116 hc[i]=(char *)malloc((n-start)*sizeof(char)); 117 //strcpy(hc[i],&cd[start]); 118 for(j=0;j<n-1;j++) 119 { 120 if(cd[j]==\'0\'||cd[j]==\'1\') 121 printf("%c",cd[j]); 122 } 123 printf("\\t"); 124 for(j=0;j<n-1;j++) 125 { 126 cd[j]=\' \'; 127 } 128 } 129 free(cd); 130 } 131 void main() 132 { 133 HuffmanTree ht1; 134 HuffmanCode hc; 135 char ch[20]; 136 int i,a,w[20]; 137 printf("请输入字符个数(小于20):"); 138 scanf("%d",&a); 139 printf("请输入字符:"); 140 getchar(); 141 for(i=1;i<=a;i++) 142 { 143 ch[i]=getchar(); 144 } 145 getchar(); 146 printf("请输入各个字符对应的权值:"); 147 for(i=1;i<=a;i++) 148 { 149 scanf("%d",&w[i]); 150 } 151 CrtHuffmanTree(ht1,w,a); 152 printf("\\n\\t\\ts对各字符的哈夫曼树编码\\n"); 153 printf("\\t字符\\t"); 154 for(i=1;i<=a;i++) 155 { 156 printf("%c\\t",ch[i]); 157 158 } 159 printf("\\n\\t权值\\t"); 160 for(i=1;i<=a;i++) 161 printf("%d\\t",w[i]); 162 printf("\\n 哈夫曼编码\\t"); 163 CrtHuffmanCode(ht1,hc,a); 164 printf("\\n"); 165 }
以上是关于求哈夫曼树的编码的主要内容,如果未能解决你的问题,请参考以下文章