赫夫曼樹

赫夫曼樹是一種基於赫夫曼編碼的二叉樹。赫夫曼編碼是一種無損編碼方式,假設一個字符的出現頻率越高,則編碼的位數越少,從而在傳輸數據時佔用的帶寬更小。赫夫曼樹的構建方法是,先按照字符出現的頻率構建一個森林,然後迭代地將頻率較小的樹合併成一個新的樹,直到只剩下一棵樹為止。

一、赫夫曼編碼的應用

赫夫曼編碼是一種無損壓縮編碼,通常用於圖像、音頻、視頻等數據傳輸和存儲中。由於這些數據通常需要傳輸的時間很長,因此對於它們的壓縮和解壓速度要求非常高。而赫夫曼編碼可以根據字符出現的頻率來確定每個字符的編碼,從而實現儘可能小的壓縮比。

二、赫夫曼樹的構建

赫夫曼樹的構建是一個迭代的過程,首先需要對文本中的字符進行一次掃描,以統計每個字符出現的頻率。然後將每個字符視為一棵以其出現頻率為根節點的樹,並按照頻率從小到大排序。

// C++代碼示例
struct node {
    char ch; // 字符
    int freq; // 頻率
    node * left, * right; // 左右孩子
};

node * buildHuffmanTree(string s) {
    // 統計字符頻率
    map freq;
    for (char c : s) {
        freq[c]++;
    }
    // 初始化森林
    vector forest;
    for (auto p : freq) {
        node * t = new node;
        t->ch = p.first;
        t->freq = p.second;
        t->left = t->right = nullptr;
        forest.push_back(t);
    }
    // 構建赫夫曼樹
    while (forest.size() > 1) {
        sort(forest.begin(), forest.end(), [](node * a, node * b) { return a->freq freq; });
        node * l = forest[0], * r = forest[1];
        node * p = new node;
        p->ch = 0;
        p->freq = l->freq + r->freq;
        p->left = l;
        p->right = r;
        forest.erase(forest.begin(), forest.begin()+2);
        forest.push_back(p);
    }
    return forest[0];
}

三、赫夫曼編碼的計算

赫夫曼編碼計算的過程是從根節點開始,每次遇到左孩子則標記1,遇到右孩子則標記0,直到遍歷到葉子節點。遍歷到葉子節點時得到的01串就是該葉子節點對應的編碼。由於赫夫曼編碼的特殊性質,任何一個編碼都不是另一個編碼的前綴,因此可以方便地解碼。

// C++代碼示例
void getHuffmanCode(node * root, string code, map & huffmanCode) {
    if (root == nullptr) return;
    if (root->left == nullptr && root->right == nullptr) {
        huffmanCode[root->ch] = code;
        return;
    }
    getHuffmanCode(root->left, code+"1", huffmanCode);
    getHuffmanCode(root->right, code+"0", huffmanCode);
}

四、赫夫曼樹的性質

赫夫曼樹的高度和字符的出現頻率有關係,出現頻率較高的字符在樹中的深度較小,出現頻率較低的字符在樹中的深度較大。因此,赫夫曼樹是一種帶權路徑最短的樹。

五、小結

赫夫曼樹是一種基於赫夫曼編碼的二叉樹,用於提供無損壓縮編碼方案。它的構建過程是一個迭代的過程,每次將森林中頻率較小的樹合併成一個新的樹,直到只剩下一棵樹為止。赫夫曼編碼計算的過程是從根節點開始,每次遇到左孩子則標記1,遇到右孩子則標記0,直到遍歷到葉子節點。赫夫曼樹具有帶權路徑最短的性質,即出現頻率較高的字符在樹中的深度較小,出現頻率較低的字符在樹中的深度較大。

原創文章,作者:FKZMR,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/371432.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FKZMR的頭像FKZMR
上一篇 2025-04-23 00:48
下一篇 2025-04-23 00:48

發表回復

登錄後才能評論