赫夫曼編碼是一種廣泛用於資料壓縮的問題,該演算法的主要優勢在於節約了儲存和傳輸成本。
舉乙個例子:
假設要傳輸的資料為
那麼傳輸成本就是:
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 行...