不定长哈夫曼树
Posted dalgleish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不定长哈夫曼树相关的知识,希望对你有一定的参考价值。
原理参考《算法导论》,我借用了stl中的deque类,这样方便构造书中说的有序队列Q。其次,本博客的所有代码都采用C和C++混编形式,所以建议使用VS2015及其以上版本编译代码。
代码如下
声明一个Huffman类以及对应的节点数据
typedef struct _Huffnode { _Huffnode(int _key, int _freq) :p(NULL), l(NULL), r(NULL), key(_key), freq(_freq) {} ~_Huffnode() { //printf("%c delete ", key); } int freq, key; _Huffnode *l, *r, *p; }Huffnode, *pHuffnode; struct Compare { bool operator()(const _Huffnode *lhs, const _Huffnode *rhs) { return lhs->freq < rhs->freq; } }; class Huffman { public: Huffman(int *keys, int *freqs, int n) :root(NULL) { Huffman_init(keys, freqs, n); } Huffman *Huffman_init(int *keys, int *freqs, int n); ~Huffman(){ Huffman_empty(root); } Huffnode *Huffman_root(); void Huffman_print(Huffnode *x, std::string str); void Huffman_empty(Huffnode *x); private: Huffnode *root; std::deque<Huffnode *> Q;//优先队列 };
对应的成员函数实现
Huffman_init成员函数,构建Huffman树
Huffman *Huffman::Huffman_init(int *keys, int *freqs, int n) { Huffnode *q, *left, *right; for (int i = 0; i < n; i++) { q = new Huffnode(keys[i], freqs[i]); Q.insert(std::upper_bound(Q.begin(), Q.end(), q, Compare()), q);//从小到大的排序 } while (Q.size() != 1) {//至少保证有两个节点 left = Q.front(); Q.pop_front(); right = Q.front(); Q.pop_front();//两个次小节点 q = new Huffnode(‘.‘, left->freq + right->freq); q->l = left; q->r = right; Q.insert(std::upper_bound(Q.begin(), Q.end(), q, Compare()), q);//加入到队列 } root = Q.front(); Q.pop_front(); return this; }
Huffman_print成员函数,输出对应的关键字key的变长字码
void Huffman::Huffman_print(Huffnode *x, std::string str) { if (x == NULL) return; if (x->key != ‘.‘)//跳过节点‘.‘ printf("%c:%s ", x->key, str.c_str()); Huffman_print(x->l, str + "0"); Huffman_print(x->r, str + "1"); }
Huffman_empty成员函数,像二叉树一样,采用后续删除节点
void Huffman::Huffman_empty(Huffnode *x) { if (x != NULL) { if (x != NULL) { Huffman_empty(x->l); Huffman_empty(x->r); delete x;//后续删除 } } }
数据录入
int key[] = { ‘f‘,‘e‘,‘c‘,‘b‘,‘a‘,‘d‘ }, freq[] = { 5,9,12,13,45,16 };
Main函数
int main() { int key[] = { ‘f‘,‘e‘,‘c‘,‘b‘,‘a‘,‘d‘ }, freq[] = { 5,9,12,13,45,16 }; Huffman huff(key, freq, sizeof(key) / sizeof(key[0])); huff.Huffman_print(huff.Huffman_root()," "); return 0; }
结果图
对应树上的结果
代码均经过测试,结果正确!
以上是关于不定长哈夫曼树的主要内容,如果未能解决你的问题,请参考以下文章