上個學期做的課程設計,關於Huffman樹的編碼譯碼。

要求:

輸入Huffman樹各個葉結點的字元和權值,建立Huffman樹並執行編碼操作

輸入一行僅由01組成的電文字串,根據建立的Huffman樹進行譯碼操作,程式最後輸出譯碼後的結果

Huffman.h定義了樹的結點資訊,各種操作。GCC編譯通過。

  1. #ifndef HUFFMAN_H_INCLUDED
  2. #define HUFFMAN_H_INCLUDED
  3. #include <iostream>
  4. #include <stdlib.h>
  5. #include <string>
  6.  
  7. #define leafNumber 20
  8. #define totalNumber 39
  9. #define maxValue 100
  10. using namespace std;
  11.  
  12. //權值型別, 這裡定義為int
  13. typedef int WType;
  14.  
  15. //樹的結點型別, 這裡定義為char, 表示字元
  16. typedef char TElemType;
  17.  
  18. //Huffman樹結點資訊定義
  19. typedef struct HuffmanNode{
  20. TElemType data;
  21. WType weight;
  22. int left_child;
  23. int right_child;
  24. int parent;
  25. string code; //每個結點的編碼, 定義為 string 類
  26. };
  27.  
  28. //Huffman樹結構定義
  29. typedef struct HuffmanTree{
  30. HuffmanNode elem[totalNumber];
  31. int currentNumber;
  32. };
  33.  
  34. /*
  35. *構建Huffman樹
  36. */
  37. void createHuffmanTree( HuffmanTree &HT, WType w[], int n ) {
  38. int i, j, p1, p2, min1, min2;
  39. for( i = ; i < n; i++ ) HT.elem[i].weight = w[i];
  40. for( i = ; i < * n - ; i++ )
  41. HT.elem[i].parent = HT.elem[i].left_child = HT.elem[i].right_child = -;
  42. for( i = n; i < * n - ; i++ ) {
  43. min1 = min2 = maxValue;
  44. for( j = ; j < i; j++ ) {
  45. if( HT.elem[j].parent == - )
  46. if( HT.elem[j].weight < min1 ) {
  47. p2 = p1;
  48. min2 = min1;
  49. p1 = j;
  50. min1 = HT.elem[j].weight;
  51. }
  52. else if( HT.elem[j].weight < min2 ) {
  53. p2 = j;
  54. min2 = HT.elem[j].weight;
  55. }
  56. }
  57. HT.elem[i].left_child = p1;
  58. HT.elem[i].right_child = p2;
  59. HT.elem[i].weight = HT.elem[p1].weight + HT.elem[p2].weight;
  60. HT.elem[p1].parent = HT.elem[p2].parent = i;
  61. }
  62. HT.currentNumber = * n - ;
  63. }
  64.  
  65. /*
  66. *對Huffman樹每個結點進行編碼
  67. */
  68. void Coding( HuffmanTree &HT, int n ) {
  69.  
  70. //當前節點下標
  71. int current = ;
  72. //父節點下標
  73. int parent = ;
  74. for( int i = * n - ; i >= ; i-- ) {
  75.  
  76. current = i;
  77. parent = HT.elem[current].parent;
  78. /*
  79. if( parent == -1 ) HT.elem[current].code[0] = '0';
  80. else {
  81. if( HT.elem[parent].left_child == current ) {
  82. strcat( HT.elem[current].code, HT.elem[parent].code );
  83. strcat( HT.elem[current].code, "0" );
  84. }
  85. if( HT.elem[parent].right_child == current ) {
  86. strcat( HT.elem[current].code, HT.elem[parent].code );
  87. strcat( HT.elem[current].code, "1" );
  88. }
  89. }
  90. */
  91.  
  92. while (parent != -)
  93. {
  94. if (HT.elem[parent].left_child == current) HT.elem[i].code += "";
  95. else HT.elem[i].code += "";
  96.  
  97. current = parent;
  98. parent = HT.elem[current].parent;
  99. }
  100.  
  101. //HT.elem[current].code += "0";
  102. reverse( HT.elem[i].code.begin(), HT.elem[i].code.end() );
  103.  
  104. }
  105.  
  106. }
  107.  
  108. /*
  109. *譯碼
  110. */
  111. void decode( HuffmanTree &HT, int n ) {
  112. cout << "輸入電文: ";
  113. char ch[];
  114. gets( ch );
  115.  
  116. int i = ;
  117. int parent;
  118. int root = * n - ;
  119. int index = root;
  120. int count = ;
  121. int len = strlen( ch );
  122. while( ch[i] != '#' ) {
  123. if( ch[i] == '' ) {
  124. index = HT.elem[index].left_child;
  125. //cout << "經過0" << endl;
  126. //cout << index << endl;
  127. //count++;
  128. }
  129. else if( ch[i] == '' ) {
  130. index = HT.elem[index].right_child;
  131. //cout << "經過1" << endl;
  132. //cout << index << endl;
  133. //count++;
  134. }
  135. if( HT.elem[index].left_child == - && HT.elem[index].right_child == - ) {
  136. cout << HT.elem[index].data;
  137. index = root;
  138. //i += count;
  139. //count = 0;
  140. //cout << index << endl;
  141. }
  142. i++;
  143. }
  144. }
  145. /*
  146. *遍歷
  147. */
  148. void PreOrder( HuffmanTree &HT, int n ) {
  149. for( int i = ; i < n; i++ ) {
  150. cout << "字元: " << HT.elem[i].data << ", " << "權值: " << HT.elem[i].weight << " Huffman編碼: " << HT.elem[i].code << endl;
  151. }
  152. };
  153.  
  154. #endif // HUFFMAN_H_INCLUDED
  1. #include "Huffman.h"
  2. int main() {
  3. HuffmanTree HT;
  4. HT.elem[].data = 'A';
  5. HT.elem[].data = 'B';
  6. HT.elem[].data = 'C';
  7. HT.elem[].data = 'D';
  8. HT.elem[].data = 'E';
  9. WType weight[] = { , , , , };
  10. //WType weight[] = { 5,7,2,13 };
  11. createHuffmanTree( HT, weight, );
  12. Coding( HT, );
  13. PreOrder( HT, );
  14.  
  15. cout << endl << endl;
  16. for( int i = ; i < ; i++ )
  17. cout << "Node " << i << " Code: " << HT.elem[i].code << endl;
  18.  
  19. cout << endl << endl;
  20. for( int i = ; i < ; i++ ) {
  21. cout << "Node " << i << ": " << "weight = " << HT.elem[i].weight << ", parent = " << HT.elem[i].parent << ", left_child = " << HT.elem[i].left_child
  22. << ", right_child = " << HT.elem[i].right_child << endl;
  23. }
  24. decode( HT, );
  25. return ;
  26. }

執行截圖: