哈夫曼树

  1. #include <stdio.h>
  2. #define N 50 /*叶子结点数*/
  3. #define M 2*N-1 /*树中结点总数*/
  4. typedef struct
  5. {
  6. char data; /*结点值*/
  7. double weight; /*权重*/
  8. int parent; /*双亲结点*/
  9. int lchild; /*左孩子结点*/
  10. int rchild; /*右孩子结点*/
  11. } HTNode;
  12. typedef struct
  13. {
  14. char cd[N]; /*存放哈夫曼码*/
  15. int start;
  16. } HCode;
  17. void CreateHT(HTNode ht[],int n)
  18. {
  19. int i,k,lnode,rnode;
  20. double min1,min2;
  21. for (i=0;i<2*n-1;i++) /*所有结点的相关域置初值-1*/
  22. ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
  23. for (i=n;i<2*n-1;i++) /*构造哈夫曼树*/
  24. {
  25. min1=min2=32767; /*lnode和rnode为最小权重的两个结点位置*/
  26. lnode=rnode=-1;
  27. for (k=0;k<=i-1;k++)
  28. if (ht[k].parent==-1) /*只在尚未构造二叉树的结点中查找*/
  29. {
  30. if (ht[k].weight<min1)
  31. {
  32. min2=min1;rnode=lnode;
  33. min1=ht[k].weight;lnode=k;
  34. }
  35. else if (ht[k].weight<min2)
  36. {
  37. min2=ht[k].weight;rnode=k;
  38. }
  39. }
  40. ht[i].weight=ht[lnode].weight+ht[rnode].weight;
  41. ht[i].lchild=lnode;ht[i].rchild=rnode;
  42. ht[lnode].parent=i;
  43. ht[rnode].parent=i;
  44. }
  45. }
  46. void CreateHCode(HTNode ht[],HCode hcd[],int n)
  47. {
  48. int i,f,c;
  49. HCode hc;
  50. for (i=0;i<n;i++) /*根据哈夫曼树求哈夫曼编码*/
  51. {
  52. hc.start=n;c=i;
  53. f=ht[i].parent;
  54. while (f!=-1) /*循序直到树根结点*/
  55. {
  56. if (ht[f].lchild==c) /*处理左孩子结点*/
  57. hc.cd[hc.start--]='0';
  58. else /*处理右孩子结点*/
  59. hc.cd[hc.start--]='1';
  60. c=f;f=ht[f].parent;
  61. }
  62. hc.start++; /*start指向哈夫曼编码最开始字符*/
  63. hcd[i]=hc;
  64. }
  65. }
  66. void DispHCode(HTNode ht[],HCode hcd[],int n)
  67. {
  68. int i,k;
  69. double sum=0,m=0;
  70. int j;
  71. printf("输出哈夫曼编码:\n"); /*输出哈夫曼编码*/
  72. for (i=0;i<n;i++)
  73. {
  74. j=0;
  75. printf(" %c:",ht[i].data);
  76. for (k=hcd[i].start;k<=n;k++)
  77. {
  78. printf("%c",hcd[i].cd[k]);
  79. j++;
  80. }
  81. m+=ht[i].weight;
  82. sum+=ht[i].weight*j;
  83. printf("\n");
  84. }
  85. }
  86. void main()
  87. {
  88. int n=5,i; /*n表示初始字符串的个数*/
  89. char str[]={'a','b','c','d','e'};
  90. double fnum[]={4,2,1,7,3};
  91. HTNode ht[M];
  92. HCode hcd[N];
  93. for (i=0;i<n;i++)
  94. {
  95. ht[i].data=str[i];
  96. ht[i].weight=fnum[i];
  97. }
  98. printf("\n");
  99. CreateHT(ht,n);
  100. CreateHCode(ht,hcd,n);
  101. DispHCode(ht,hcd,n);
  102. printf("\n");
  103. }