既然是學習哈夫曼編碼,我們首先需要知道什麼是哈夫曼樹:給定n個權值作為n個葉子結點,構造一棵二叉樹,若帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(huffman tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。
在日常計算機的使用中,我們一定會出現下面這種情況:假如給定a、b、c、d、e五個字元,它們在文字中出現的概率如下圖所示:
字元概率
a0.12
b0.40
c0.15
d0.05
e0.25
我們現在要將文字編碼成0/1序列從而使得計算機能夠進行讀取和計算。為了保證每個字元的獨一性,所以我們給予不同的的字元以不同的編碼。如果給每個字元賦予等長的編碼的話,會使得平均的編碼長度過長,影響計算時的效能,浪費計算機的資源(定長編碼的缺點)。這時我們就想到了變長編碼,理所當然的,給出現概率較大的字元賦予較短的編碼,概率較小的字元賦予較長的編碼,這樣在計算的時候不就可以節省很多時間了嗎?可這樣我們又面臨到了乙個巨大的問題,我們來看下面這種情況,我們對字元進行編碼:
字元概率編碼a
0.1201b
0.400c
0.1500d
0.0510e
0.25
1假設現在文字中的字元是bcd,轉換之後的0/1序列為00010,可我們要在轉換成文字的時候究竟是把第一位的0讀作b還是把前兩位的00讀作c呢?為了解決這個問題,就又有了字首碼的概念。顧名思義,字首碼的含義就是任意字元的編碼都不是其他字元編碼的字首。那麼該如何形成字首碼呢?首先我們要構造一棵二叉樹,指向左孩子的"邊"記作0,指向右孩子的點記作「1」,葉子節點為代編碼的字元,出現概率越大的字元離根的距離就越近。
字元概率編碼a
0.12
0100
b0.401c
0.15
0101
d0.05
011e
0.25
00我們在前面提到:哈夫曼樹的帶權路徑最小,所以有哈夫曼樹構成的字首碼記作哈夫曼編碼。哈夫曼作為已知的最佳無失真壓縮演算法,滿足字首碼的性質,可以即時解碼。
哈夫曼編碼(huffman coding),又稱霍夫曼編碼,是一種編碼方式,哈夫曼編碼是可變字長編碼(vlc)的一種。huffman於2023年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做huffman編碼(有時也稱為霍夫曼編碼)。實現哈夫曼編碼的主要思路為從指定的檔案中讀出文字,首先通過遍歷獲得各個字元出現的概率,根據出現概率的大小構造二叉樹,在此基礎上進行編碼解碼。
public class nodeimplements comparable>
public t getdata()
public void setdata(t data)
public double getweight()
public void setweight(double weight)
public nodegetleft()
public void setleft(nodeleft)
public nodegetright()
public void setright(noderight)
public string getcode()
public void setcode(string str)
@override
public string tostring()
@override
public int compareto(nodeother)
if(other.getweight() < this.getweight())
return 0;}}
public nodecreatetree(list> nodes)
return nodes.get(0);
}
public list> breadth(noderoot)
while (!queue.isempty())
if (node.getright() != null)
}return list;
}
接下來我們首先從指定的檔案中讀取文字:
file file = new file("g:/usually/input/input1.txt");
public class readtxt ;
int number = new int;
public string txtstring(file file)
br.close();
}catch(exception e)
return result.tostring();
}public void num(string string)
huffmantree huffmantree = new huffmantree();
noderoot = huffmantree.createtree(list);
list2=huffmantree.breadth(root);
for(int i = 0;i0){
temp2 = temp2+"" +list5.get(0);
list5.remove(0);
for(int i=0;i最後得到的結果:
哈夫曼編碼實現
define huffmancode char typedef struct node huffmantree struct node 葉節點為n的哈夫曼樹有2 n 1個節點 用 1表示當前parent未被訪問 huffmantree createhuffmantree int wet,int n ...
實現哈夫曼編碼
include include include include include using namespace std typedef struct node vector nodes 表示結點的指標組 double char number 0 每個字元平均花費的編碼長度 const int cha...
哈夫曼編碼 哈夫曼樹
1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....