定义
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
树结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Node { public: char c; int weight; Node *left; Node *right; Node *parent; Node(char cc, int w) { c = cc; weight = w; left = NULL; right = NULL; parent = NULL; } Node(int w, Node *l, Node *r, Node *p) { c = ' '; weight = w; left = l; right = r; parent = p; } }; class HuffmanTree { Node *root;
public: HuffmanTree() { root = NULL; } ~HuffmanTree() { release(root); } void release(Node *root); void setTree(vector<Node *> &v); void enCode(string s); void deCode(string str); };
|
构造树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| void HuffmanTree::setTree(vector<Node *> &v) { sort(v.begin(), v.end(), cmp); while (int(v.size() != 1)) { int n = int(v.size()) - 1; Node *p1 = v[n]; Node *p2 = v[n - 1]; Node *temp = new Node((p1->weight + p2->weight), p1, p2, NULL); p1->parent = temp; p2->parent = temp; v.erase(v.end() - 1); v.erase(v.end() - 1); v.push_back(temp); sort(v.begin(), v.end(), cmp); } root = v[0]; } bool cmp(Node *p1, Node *p2) { return p1->weight > p2->weight; }
|
编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| void HuffmanTree::enCode(string str) { Node *p = root; if (!p) return; stack<Node *> s; vector<Node> v; s.push(root); while (!s.empty()) { Node *temp = s.top(); if (!temp->left && !temp->right) v.push_back(*temp); s.pop(); if (temp->right) { s.push(temp->right); } if (temp->left) { s.push(temp->left); } } for (int i = 0; i < int(str.length()); i++) { for (int j = 0; j < int(v.size()); j++) if (v[j].c == str[i]) { stack<char> stk; Node *cur; cur = &v[j]; while (cur) { if (cur->parent) { if (cur->parent->left->weight == cur->weight) { stk.push('0'); } else stk.push('1'); } cur = cur->parent; } while (!stk.empty()) { cout << stk.top(); stk.pop(); } cout << ' '; } } cout << endl; }
|
解码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void HuffmanTree::deCode(string str) { Node *p = root; if (!p) return; for (int i = 0; i < int(str.length()); i++) { if (str[i] == '0') p = p->left; else if (str[i] == '1') p = p->right; if (p->left == NULL && p->right == NULL) { cout << p->c; p = root; } } cout << 'n'; }
|
测试用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void test() { vector<Node *> v; v.push_back(new Node('S', 5)); v.push_back(new Node('U', 8)); v.push_back(new Node('C', 9)); v.push_back(new Node('E', 20)); v.push_back(new Node('!', 10)); HuffmanTree t; t.setTree(v);
t.enCode("SUCCESS!");
t.deCode("1001011101100100100111");
cout << "nn"; }
|
结果