哈夫曼編碼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 種豆子,每種豆子的總量和總價值都各不相同。怎樣裝才能讓揹包裡豆子的總價值最大呢?這個問題其實很簡單,我們只需要計算出每種豆子的單價,然後按照單價從高到低依次來裝就好了。單價從高到低排列為 黑豆 綠豆 紅豆 青豆和黃豆,...