Huffman树的编码译码
上个学期做的课程设计,关于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 = 0; i < n; i++ ) HT.elem[i].weight = w[i]; 40 for( i = 0; i < 2 * n - 1; i++ ) 41 HT.elem[i].parent = HT.elem[i].left_child = HT.elem[i].right_child = -1; 42 for( i = n; i < 2 * n - 1; i++ ) { 43 min1 = min2 = maxValue; 44 for( j = 0; j < i; j++ ) { 45 if( HT.elem[j].parent == -1 ) 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 = 2 * n - 1; 63 } 64 65 /* 66 *对Huffman树每个结点进行编码 67 */ 68 void Coding( HuffmanTree &HT, int n ) { 69 70 //当前节点下标 71 int current = 0; 72 //父节点下标 73 int parent = 0; 74 for( int i = 2 * n - 2 ; i >= 0; 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 93 while (parent != -1) 94 { 95 if (HT.elem[parent].left_child == current) HT.elem[i].code += "0"; 96 else HT.elem[i].code += "1"; 97 98 current = parent; 99 parent = HT.elem[current].parent; 100 } 101 102 //HT.elem[current].code += "0"; 103 reverse( HT.elem[i].code.begin(), HT.elem[i].code.end() ); 104 105 } 106 107 } 108 109 /* 110 *译码 111 */ 112 void decode( HuffmanTree &HT, int n ) { 113 cout << "输入电文: "; 114 char ch[100]; 115 gets( ch ); 116 117 int i = 0; 118 int parent; 119 int root = 2 * n - 2; 120 int index = root; 121 int count = 0; 122 int len = strlen( ch ); 123 while( ch[i] != '#' ) { 124 if( ch[i] == '0' ) { 125 index = HT.elem[index].left_child; 126 //cout << "经过0" << endl; 127 //cout << index << endl; 128 //count++; 129 } 130 else if( ch[i] == '1' ) { 131 index = HT.elem[index].right_child; 132 //cout << "经过1" << endl; 133 //cout << index << endl; 134 //count++; 135 } 136 if( HT.elem[index].left_child == -1 && HT.elem[index].right_child == -1 ) { 137 cout << HT.elem[index].data; 138 index = root; 139 //i += count; 140 //count = 0; 141 //cout << index << endl; 142 } 143 i++; 144 } 145 } 146 /* 147 *遍历 148 */ 149 void PreOrder( HuffmanTree &HT, int n ) { 150 for( int i = 0; i < n; i++ ) { 151 cout << "字符: " << HT.elem[i].data << ", " << "权值: " << HT.elem[i].weight << " Huffman编码: " << HT.elem[i].code << endl; 152 } 153 }; 154 155 156 #endif // HUFFMAN_H_INCLUDED
#include "Huffman.h" int main() { HuffmanTree HT; HT.elem[0].data = 'A'; HT.elem[1].data = 'B'; HT.elem[2].data = 'C'; HT.elem[3].data = 'D'; HT.elem[4].data = 'E'; WType weight[] = { 7, 5, 2, 4, 6 }; //WType weight[] = { 5,7,2,13 }; createHuffmanTree( HT, weight, 5 ); Coding( HT, 5 ); PreOrder( HT, 5 ); cout << endl << endl; for( int i = 0; i < 9; i++ ) cout << "Node " << i << " Code: " << HT.elem[i].code << endl; cout << endl << endl; for( int i = 0; i < 9; i++ ) { cout << "Node " << i << ": " << "weight = " << HT.elem[i].weight << ", parent = " << HT.elem[i].parent << ", left_child = " << HT.elem[i].left_child << ", right_child = " << HT.elem[i].right_child << endl; } decode( HT, 5 ); return 0; }
运行截图: