哈弗曼编码
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define MAXNUM 10 #define MAXBIT 10 #define MINWEIGHT 1000000 typedef struct { char value; // 输入结点代号,如A, B, C... int parent; /* 父子关系用下标值进行关联 */ int lchild; int rchild; int weight; // 自身权重 }HTNODE; typedef struct { char bit[MAXBIT]; // 存储编码 }HTCODE; /******************************************************************************************/ void Init(int &n, HTNODE *HTNode) { cout << "Input the Number of Object, n = "; cin >> n; for(int i = 0; i < n; i++) { HTNode[i].value = 65 + i; // 默认代号A, B, C... HTNode[i].parent = -1; HTNode[i].lchild = -1; HTNode[i].rchild = -1; cout << "weight[" << i << "] = "; cin >> HTNode[i].weight; } int m = 2 * n - 1; for(int i = n; i < m; i++) { HTNode[i].value = '*'; // 合成结点代号 HTNode[i].parent = -1; HTNode[i].lchild = -1; HTNode[i].rchild = -1; HTNode[i].weight = 0; } } void Select(int &fstSmallest, int &sndSmallest, HTNODE *HTNode, int i) { fstSmallest = -1; sndSmallest = -1; int fstSWeight = MINWEIGHT; int sndSWeight = MINWEIGHT; for(int k = 0; k < i; k++) { if(HTNode[k].parent == -1) { if(HTNode[k].weight <= fstSWeight) { sndSmallest = fstSmallest; sndSWeight = fstSWeight; fstSmallest = k; fstSWeight = HTNode[k].weight; } else if(HTNode[k].weight>fstSWeight && HTNode[k].weight<sndSWeight) { sndSmallest = k; sndSWeight = HTNode[k].weight; } } } } void BuildHuffmanTree(int n, HTNODE *HTNode) { int m = 2 * n - 1; // 可计算出哈夫曼树结点总数 int fstSmallest, sndSmallest; // 分别标记下标值 for(int i = n; i < m; i++) { Select(fstSmallest, sndSmallest, HTNode, i); HTNode[fstSmallest].parent = i; HTNode[sndSmallest].parent = i; HTNode[i].lchild = fstSmallest; HTNode[i].rchild = sndSmallest; HTNode[i].weight = HTNode[fstSmallest].weight + HTNode[sndSmallest].weight; } } void PrintHuffmanTree(int n, HTNODE *HTNode) { int m = 2 * n - 1; for(int i = 0; i < m; i++) { cout << "\ni = " << i; printf(" value = %c", HTNode[i].value); printf(" parent = %2d", HTNode[i].parent); printf(" lchild = %2d", HTNode[i].lchild); printf(" rchild = %2d", HTNode[i].rchild); printf(" weight = %2d", HTNode[i].weight); cout << endl; } } void HuffmanCoding(int n, HTNODE *HTNode, HTCODE *HTCode) { int j, start; char Tbit[MAXBIT]; for(int i = 0; i < n; i++) /* 编码i结点 */ { start = MAXBIT-1; int temp_child = i; // 临时孩子 int temp_parent = HTNode[i].parent; // 临时父亲 while(temp_parent != -1) { cout << "temp_child = " << temp_child; // Debug 编码过程 cout << " temp_parent = " << temp_parent << endl; // Debug 编码过程 if(HTNode[temp_parent].lchild == temp_child) Tbit[--start] = '0'; else Tbit[--start] = '1'; temp_child = temp_parent; temp_parent = HTNode[temp_child].parent; } strcpy(HTCode[i].bit, &Tbit[start]); cout << "bit = " << HTCode[i].bit << endl; // Debug 编码过程 } } void HuffmanDecoding(int n, HTNODE *HTNode) { int it, flag = 1; int m = 2 * n - 1; char str[MAXBIT], *p; printf("\nInput the String, str = "); scanf("%s", str); p = str; for(int i = 0; i < m; i++) // 先定位到根节点 if(HTNode[i].parent == -1) { it = i; break; } while(*p != '\0') { if(HTNode[it].lchild==-1 && HTNode[it].rchild==-1) // 编码串过长 { flag = -1; break; } if(p[0] == '0') it = HTNode[it].lchild; else it = HTNode[it].rchild; p++; } if(HTNode[it].lchild!=-1 && HTNode[it].rchild!=-1) // 编码串过短 { flag = -1; } if(flag == -1) printf("Input String is Error!\n"); else printf("Decoding Result is: %c\n", HTNode[it].value); } /******************************************************************************************/ int main() { int n; HTNODE HTNode[MAXNUM]; // MAXNUM表示哈夫曼树结点数上限 HTCODE HTCode[MAXNUM]; Init(n, HTNode); BuildHuffmanTree(n, HTNode); PrintHuffmanTree(n, HTNode); HuffmanCoding(n, HTNode, HTCode); HuffmanDecoding(n, HTNode); return 0; }