原理参考《算法导论》,我借用了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\n", 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) :huffman_root(NULL) { Huffman_init(keys, freqs, n); } ~Huffman(){ Huffman_empty(huffman_root); } Huffnode *Huffman_root(); Huffnode *Huffman_init(int *keys, int *freqs, int n); void Huffman_print(Huffnode *x, std::string str); void Huffman_empty(std::deque<Huffnode *> x); private: std::deque<Huffnode *> Q, huffman_root;//优先队列 };
对应的成员函数实现
Huffman_init成员函数,构建Huffman树
Huffnode *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);//从小到大的排序 } for (std::deque<Huffnode *>::iterator itr = Q.begin(); itr != Q.end(); itr++) printf("%c:%d ", (*itr)->key, (*itr)->freq); printf("\n"); while (Q.size() != 1) {//至少保证有两个节点 left = Q[0]; 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);//加入到队列 huffman_root.push_front(q->r); huffman_root.push_front(q->l); } q = Q.front(); Q.pop_front(); huffman_root.push_front(q); return huffman_root[0]; }
Huffman_print成员函数,输出对应的关键字key的变长字码
void Huffman::Huffman_print(Huffnode *x, std::string str) { if (x == NULL) return; if (x->key != '.')//跳过节点'.' printf("%c:%s\n", x->key, str.c_str()); Huffman_print(x->l, str + "0"); Huffman_print(x->r, str + "1"); }
Huffman_empty成员函数
void Huffman::Huffman_empty(std::deque<Huffnode *> x) { while (!x.empty()) { delete x.back(); x.pop_back(); } }
数据录入
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=new Huffman(key, freq, sizeof(key) / sizeof(key[0])); huff->Huffman_print(huff->Huffman_root()," "); printf("对象释放....\n"); delete huff; if (_CrtDumpMemoryLeaks()) printf("内存泄漏,请使用F5 debug模式查看!\n");//内存泄漏检测 else printf("无内存泄漏!\n"); return 0; }
结果图
对应树上的结果
代码均经过测试,结果正确!