1. 程式人生 > >不定長哈夫曼樹

不定長哈夫曼樹

及其 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;
}

結果圖

技術分享圖片

對應樹上的結果

技術分享圖片

代碼均經過測試,結果正確!

不定長哈夫曼樹