Huffman霍夫曼壓縮編碼演算法實現分析

2021-07-01 18:14:25 字數 2822 閱讀 1135

哈夫曼編碼huffman方法於2023年問世,迄今為止仍經久不衰,廣泛應用於各種資料壓縮技術中,且仍不失為熵編碼中的最佳編碼方法,deflate等壓縮演算法也是結合了huffman演算法的。

採用霍夫曼編碼時有兩個問題值得注意:

①霍夫曼碼沒有錯誤保護功能,在解碼時,如果碼串中沒有錯誤,那麼就能乙個接乙個地正確譯出**。但如果碼串中有錯誤,哪僅是1位出現錯誤,不但這個碼本身譯錯,更糟糕的是一錯一大串,全亂了套,這種現象稱為錯誤傳播(error propagation)。計算機對這種錯誤也無能為力,說不出錯在**,更談不上去糾正它。

②霍夫曼碼是可變長度碼,因此很難隨意查詢或呼叫壓縮檔案中間的內容,然後再解碼,這就需要在儲存**之前加以考慮。儘管如此,霍夫曼碼還是得到廣泛應用。

/*

霍夫曼編碼模型:思想是壓縮資料出現概率高的用短編碼,出現概率低的用長編碼,且每個字元編碼都不一樣。

壓縮資料單個字元出現的概率抽象為葉子節點的權值,huffman樹葉子節點到根節點的編碼(是父節點左子節點那麼填0,否則填1)

作為字元的唯一編碼.

實現時候需要注意的規則:

1)最左的放置在左邊,作為父節點的左節點。

2)每次都從沒有設定父節點的所用節點中(葉子和分支節點一樣對待),從陣列小下標到大下標優先順序遍歷。

3)當前搜尋的次數i + n作為新生成的分支節點的陣列下標。

實現的過程和具體演算法思想:

兩個資料結構:

乙個是huffman樹節點結構體,乙個是從霍夫曼樹葉子節點編碼的結構體。

兩個處理過程:

1)建立huffman樹:

基本思想是:對於沒有設定父節點的節點集選出最小的兩個,最小的放置在左邊,次小的放置在右邊

設定好父節點和左右子節點關係,方便獲得霍夫曼編碼。

2) 從huffman樹得到葉子節點的huffman編碼:

基本思想:對於建立好的huffman樹的每個葉子節點,由編碼的陣列的末端也是從葉子節點最底端,往上遍歷

如果是父節點的左節點那麼用編碼陣列填1,如果是父節點的右節點那麼編碼陣列填0,一直往上追溯到根節點。

*/// 以下是實現的**,在win32編譯通過。

#include "stdafx.h"

#define maxcodelen 7

#define maxweight 10000

struct taghuffmannode

;struct taghuffmancode

;void huffman(int w, int n, taghuffmannode ht, taghuffmancode hc)

else

ht[i].m_nparent = 0;

ht[i].m_nlchild = ht[i].m_nrchild = -1;

} // 構造一顆huffman樹,設定n-1個分支節點(非葉子),

// 基本思想是:對於沒有設定父節點的節點集選出最小的兩個,最小的放置在左邊,次小的放置在右邊

// 設定好父節點和左右子節點關係,方便獲得霍夫曼編碼

int ncurminweight,ncursecondminweight;

int ncurleftchild, ncurrightchild;

for( int i = 0; i < n-1; i++)

else if(ht[j].m_nweight < ncursecondminweight && ht[j].m_nparent == 0)

}// 得到分支節點,設定節點關係

ht[n + i].m_nlchild = ncurleftchild;

ht[n + i].m_nrchild = ncurrightchild;

ht[n + i].m_nweight =ncurminweight + ncursecondminweight;

ht[ncurleftchild].m_nparent = n + i;

ht[ncurrightchild].m_nparent = n + i;

} // 測試用

/*for(int i = 0; i < ntotalcount; i++)

*/ // 記錄下來每個葉子節點的huffman編碼

// 基本思想:對於建立好的huffman樹的每個葉子節點,由編碼的陣列的末端也是從葉子節點最底端,往上遍歷

// 如果是父節點的左節點那麼用編碼陣列填1,如果是父節點的右節點那麼編碼陣列填0,一直往上追溯到根節點。

for(int k = 0; k < n; k++)

else if(nchild == ht[nparent].m_nrchild)

hc[k].m_nstart--;

nchild = nparent;

nparent = ht[nchild].m_nparent;

} // 因為遞減了需要增加,得到正確的起始下標

hc[k].m_nstart++; }}

int _tmain(int argc, _tchar* argv)

; const int nmaxlen = 2 * ndatanum - 1;

taghuffmannode *ht = new taghuffmannode[nmaxlen];

taghuffmancode *hc = new taghuffmancode[ndatanum];

huffman(nweigt, ndatanum, ht, hc);

for(int i = 0; i < 7; i++)

printf("\n");

} delete ht;

delete hc;

while(1);

return 0;

}

霍夫曼(Huffman)編碼學習總結

霍夫曼編碼基於字元的出現頻率實現長度最小的變長編碼 vlc jpeg中使用huffman 編碼實現大小壓縮。編碼過程基本步驟 1 掃瞄待編碼字串,計算每個包含字元的出現概率,按從小到大排列構成鏈式結構。2 自底向上構造huffman tree 3 按照字元在樹中的路徑寫出編碼 0 left,1 ri...

貪心演算法 Huffman 壓縮編碼的實現

假設我們有乙個可以容納 100 kg 物品的揹包,可以裝各種物品。我們有以下 5 種豆子,每種豆子的總量和總價值都各不相同。怎樣裝才能讓揹包裡豆子的總價值最大呢?這個問題其實很簡單,我們只需要計算出每種豆子的單價,然後按照單價從高到低依次來裝就好了。單價從高到低排列為 黑豆 綠豆 紅豆 青豆和黃豆,...

貪心演算法 Huffman 壓縮編碼的實現

假設我們有乙個可以容納 100 kg 物品的揹包,可以裝各種物品。我們有以下 5 種豆子,每種豆子的總量和總價值都各不相同。怎樣裝才能讓揹包裡豆子的總價值最大呢?這個問題其實很簡單,我們只需要計算出每種豆子的單價,然後按照單價從高到低依次來裝就好了。單價從高到低排列為 黑豆 綠豆 紅豆 青豆和黃豆,...