• 哈夫曼树

    哈夫曼树

    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. }