貪心演算法 赫夫曼編碼問題(Huffman)

2021-07-25 07:10:44 字數 1651 閱讀 7310

赫夫曼編碼是一種廣泛用於資料壓縮的問題,該演算法的主要優勢在於節約了儲存和傳輸成本。

舉乙個例子:

假設要傳輸的資料為

那麼傳輸成本就是:

45*3 + 30 * 3 + 29 * 3 + 10 * 3 + 8 * 3 + 5 * 3 = 381個字元

先合併最小頻率的2個字元對應的子樹,計算合併後的子樹的頻率;

重新排序各個子樹;

重複步驟1

重複步驟2

對二叉樹中的邊賦予0、1,得到各字元的變長編碼。

對於上舉的例子而言就是:

ef最小,首先構造ef的生成樹,重新排序

構造ef 和 d的生成樹,重新排序

構造efd 和 c 的生成樹,重新排序

構造efdc 和 b 的生成樹,重新排序

構造efdcb 和 a 的生成樹,重新排序

赫夫曼編碼後的二進位制資料為:

可以看見,利用赫夫曼思想設計之後,頻率高的字元,二進位製碼短了,頻率低的字元,二進位制碼長了,這樣就有效得減少了總得二進位制碼數。

那麼傳輸成本就是:

45*1 + 30 * 2 + 29 * 3 + 10 * 4 + 8 * 5 + 5 * 5 = 292個字元,節約了23%的成本!

把一塊無限長的木板鋸成幾塊給定長度的小木板,每次鋸都需要一定費用,費用就是當前鋸的木板的長度。給定各個要求的小木板的長度以及小木板的個數,求最小的費用。利用huffman思想,要使總費用最小,那麼每次只選取最小長度的兩塊木板相加,再把這些和累加到總費用中即可。

以需要3塊長度分別為8,10,4的木板為例,首先4和8形成乙個生成樹權值為12,接著10和12形成生成樹,權值為22。因此一開始砍乙個長度為22的木板,費用為22;接著砍4,費用總和為26,;接著砍8,費用總為34;

為了提高效率,使用優先佇列優化,並且還要注意使用long long int儲存結果。

#include

#include

#include

using

namespace

std;

int main()

if(q.size() == 1)

while(q.size() > 1)

cout

<< sum;

}

演算法導論 貪心演算法之赫夫曼編碼

討論赫夫曼編碼問題,赫夫曼編碼的思想就是變長編碼。變長編碼就是讓字元表中出現概率高的字元的編碼長度盡可能小,而出現概率高的字元的編碼長度相對較長。然後還要遵循字首碼的要求,就是任意乙個編碼都不是其他編碼的字首碼,這樣方便解碼。對於下表中的字元和相應的出現概率,有對應圖中的編碼樹 可以比較容易的看出來...

小白高階之貪心演算法 赫夫曼編碼

赫夫曼編碼是根據字元的使用頻率對字元進行編碼的一種編碼方法,其用於壓縮資料的效果非常好。一般用二叉樹表示赫夫曼編碼,使用頻率越低的字元,其深度越大。其中q表示乙個按頻率從小到大排序的優先佇列。在赫夫曼編碼的表示中,通常用字首碼的表達方法。字首碼即沒有任何碼字是其他碼字的字首,其作用是簡化解碼過程。用...

多元Huffman編碼問題 貪心演算法

在乙個操場的四周擺放著n堆石子。現要將石子有次序地合併成一堆。規定每次至少選2 堆最多選k堆石子合併成新的一堆,合併的費用為新的一堆的石子數。試設計乙個演算法,計算出將n堆石子合併成一堆的最大總費用和最小總費用。對於給定n堆石子,計算合併成一堆的最大總費用和最小總費用。input 輸入資料的第1 行...