哈夫曼编码_哈夫曼树_详细注释版本
课堂上丧心病狂要默写哈夫曼编码。。。表示已跪ORZ。
下来重新看了下,表示网上的版本有点难懂,自己搞了个简单易读版本,附带详细注释
1 #include <iostream> 2 #include <Windows.h> 3 #define INFINITY 65535 4 using namespace std; 5 typedef struct 6 { 7 int weight; //权值 8 int parent, Left, Right; //左右孩子的节点值 9 }TREE, *PTREE; 10 typedef char **TheCode;//指向TheCode(逆转编码值)的一个指针 11 void HuffmanCoding(PTREE &HuffmanTree, int *w, int n); 12 void Find_Min_(PTREE HuffmanTree,int n, int &The_Min_Numb_NO_1, int &The_Min_Numb_NO_2);//选择书中节点值较小的两个节点 13 int w[] = {8, 9,4, 12,33,56,32,45}; //各节点权值 14 void HuffmanCoding(PTREE &HuffmanTree, int *w, int n) 15 { 16 17 int m = 2 * n - 1; //哈夫曼树一共有m个节点 18 HuffmanTree = (TREE*)malloc((m + 1) * sizeof(TREE));//Huffman tree的所有节点 19 20 int The_Min_Numb_NO_1, The_Min_Numb_NO_2; //声明两个节点,其权重为最小的两个 21 22 memset(HuffmanTree, 0, (m + 1)* sizeof(TREE)); //对所有节点初始化为-0 23 for (int i = 1; i <= n; i++) 24 { 25 HuffmanTree[i].weight = *w++; //可改变为人为输入————把自动提供的数字输入到哈夫曼节点当中 26 } 27 28 //创建Huffman tree 29 for(int i = n + 1; i <= m; ++i) 30 { 31 //选择剩余节点中权值较小的The_Min_Numb_NO_1和The_Min_Numb_NO_2 32 Find_Min_(HuffmanTree, i - 1, The_Min_Numb_NO_1, The_Min_Numb_NO_2); 33 HuffmanTree[The_Min_Numb_NO_1].parent = i; 34 HuffmanTree[The_Min_Numb_NO_2].parent = i; 35 HuffmanTree[i].Left = The_Min_Numb_NO_1; 36 HuffmanTree[i].Right = The_Min_Numb_NO_2; 37 HuffmanTree[i].weight = HuffmanTree[The_Min_Numb_NO_1].weight + HuffmanTree[The_Min_Numb_NO_2].weight; 38 } 39 40 TheCode The_Inverse_Arry_; 41 int start, c, f; 42 The_Inverse_Arry_ = (TheCode)malloc((n + 1) * sizeof(char*)); 43 char* cd = (char*)malloc(n * sizeof(char)); 44 cd[n - 1] = '\0'; 45 for(int i = 1; i <= n; i++) 46 { 47 start = n - 1; 48 for(c = i, f = HuffmanTree[i].parent; f != 0; c = f, f = HuffmanTree[f].parent) 49 if (HuffmanTree[f].Left == c) //对于所有点,如果找到了他的左儿子节点 50 cd[--start] = '0'; //对于所有左节点而言,他的code值为0 51 else 52 cd[--start] = '1'; //同上,对于右边而言,code值为1 53 The_Inverse_Arry_[i] = (char*)malloc((n - start) * sizeof(char));//申明逆转数组 54 strcpy(The_Inverse_Arry_[i], &cd[start]); //逆转code数组(因为是从叶子节点往上的) 55 } 56 57 for (int i = 1; i <= n; i++) 58 { 59 cout<< HuffmanTree[i].weight<<" 的哈夫曼代码是 "; 60 cout<<The_Inverse_Arry_[i]<<endl; 61 } 62 } 63 64 void Find_Min_(PTREE HuffmanTree, int n, int &The_Min_Numb_NO_1, int &The_Min_Numb_NO_2) 65 { 66 The_Min_Numb_NO_1 = 1; 67 The_Min_Numb_NO_2 = 1; 68 int min = INFINITY; 69 int i; 70 //选择未被使用的第一个节点, 71 for (i = 1; i <= n; ++i) 72 { 73 if (HuffmanTree[i].parent == 0) 74 { 75 min = HuffmanTree[i].weight; 76 break; 77 } 78 } 79 80 //找到权值最小点The_Min_Numb_NO_1 81 for (int p = 1; p <= n; ++p) 82 { 83 if(0 == HuffmanTree[p].parent && min >= HuffmanTree[p].weight) 84 { 85 The_Min_Numb_NO_1 = p; 86 min = HuffmanTree[p].weight; 87 } 88 } 89 //找到The_Min_Numb_NO_2 90 min = INFINITY; 91 for (int q = 1; q <= n; ++q) 92 { 93 if(0 == HuffmanTree[q].parent && min >= HuffmanTree[q].weight ) 94 { 95 if( q == The_Min_Numb_NO_1) 96 continue; 97 The_Min_Numb_NO_2 = q; 98 min = HuffmanTree[q].weight; 99 } 100 } 101 } 102 int main() 103 { 104 PTREE HuffmanTree; 105 HuffmanCoding(HuffmanTree, w, 8); 106 return 0; 107 }