不定長哈夫曼樹
阿新 • • 發佈:2018-06-15
及其 string {} mage front 成員函數 code gin key
原理參考《算法導論》,我借用了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) :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\n", 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; }
結果圖
對應樹上的結果
代碼均經過測試,結果正確!
不定長哈夫曼樹