1)路徑:由乙個結點到另乙個結點之間的所有分支共同構成。
2)路徑長度:結點之間的分支數目。
3)樹的路徑長度:從樹的根結點到其他所有結點的路徑長度之和。
4)權:賦予某一實體的值。在資料結構中,實體包括結點和邊,所以對應有結點權和邊權。
5)結點的帶權路徑長度:結點與樹的根結點之間的路徑長度與結點權的乘積。
6)樹的帶權路徑長度:所有葉結點的帶權路徑長度之和。
7)哈夫曼樹(huffman tree):樹的帶權路徑長度最小的樹。
假設有8個結點n1~n8。
權值越大的結點應該離樹的根結點越近,因而先找到樹中最小的兩個結點n1和n2,並把它們作為最後一層的葉結點。
最小的兩個結點作為新結點n9的左、右子樹根結點後,又從n3~n9選出最小的兩個結點n4和n6,並把它們作為新結點n10的左、右子樹根結點。
不斷重複上面的操作,直至n1~n8都成為哈夫曼樹的葉結點。
最終得到的哈夫曼樹沒有度為1的結點,因此一棵有n個葉結點的哈夫曼樹,一共有2n-1個結點,可以儲存在乙個大小為2n-1的一維陣列中。
為了方便表示,增加乙個單元的陣列長度,從1號位置開始使用,所以陣列長度為2n。
將葉結點n1~n8儲存在前面的1~8號位置,其餘結點儲存在9~2n-1號位置。
哈夫曼樹是特殊的、帶權路徑長度最小的二叉樹,當然可以使用傳統的二叉鍊錶儲存。
但在樹的儲存結構篇裡已經提過,順序儲存結構僅適用於完全二叉樹,而二叉鍊錶存在許多空指標域,再加上哈夫曼樹的構造具有規律,而且結點數目確定,所以可以用乙個確定的一維陣列儲存。
除了0號位置空出來,其餘每個位置存放乙個結點。每個陣列元素包括四個資訊:權值、父結點編號、左子樹根結點編號和右子樹根結點編號。
typedef struct
hfnode, *hfbitree; /*陣列長度根據給定結點數n來確定*/
void creathuffmantree(hfbitree &ht, int n)
for(int i = 1; i <= n; i++)
cin>>ht[i];
/*-----構建哈夫曼樹-----*/
for(int i = n+1; i <= m; i++)
}
哈夫曼樹在通訊、編碼和資料壓縮等技術領域有著廣泛的應用,其中哈夫曼編碼是構造通訊碼的乙個典型應用。
在資料通訊、資料壓縮時,需要將資料檔案轉換成由二進位制字元0/1組成的二進位制串,這個過程稱為編碼。
編碼的方案一般有三種:
等長編碼方案
不等長編碼方案
哈夫曼編碼方案
字元編碼
字元編碼
字元編碼a00
a0a0
b01b01
b10c10
c010
c110d11
d111d
為什麼要引入哈夫曼編碼?
1)為了使頻率高的字元盡可能採用更短的編碼,而頻率低的字元可以採用稍長的編碼,構造一種不等長編碼以獲得更好的空間效率。這也是檔案壓縮技術的核心思想。
2)但不等長編碼不能隨意設計,任何乙個字元的編碼都不可以是另乙個字元的編碼的字首,不合理的編碼將有可能導致在解碼時出現二義性。
為了合理地設計不等長編碼,同時考慮各個字元的使用頻率,哈夫曼編碼出現了。
在哈夫曼樹中,權值越大的結點離根結點越近,路徑長度越短,這與使用頻率越高,編碼越短的思想相同。
在哈夫曼樹中,根結點到任何乙個葉結點的路徑都不可能是到另乙個葉結點路徑的一部分,這與任何乙個字元的編碼都不可以是另乙個字元的編碼的字首的條件相同。
因此我們可以根據每個字元出現的概率,構造出一棵哈夫曼樹。
設左分支為0,右分支為1。
我們已經知道由根結點到葉結點的路徑可以求出乙個字元的哈夫曼編碼。但是考慮到哈夫曼樹結點的儲存結構,每個結點的資訊包括:權值、父結點編號、左子樹根結點編號和右子樹根結點編號。
如果由根結點遍歷到葉結點,訪問下乙個結點時總是得考慮左、右兩個方向,顯然,這樣的求解效率很低。
反過來,如果從葉結點遍歷到根結點,訪問一下個結點,即父結點時,只需要考慮乙個方向,顯然這樣的求解目的性更強,效率也更高。
typedef char **hfcode; /*動態分配陣列儲存哈夫曼編碼表(指標陣列)*/
void creathuffmancode(hfbitree &ht, hfcode &hc, int n)
/*求出第i個字元的編碼*/
hc[i] = new char[n-start]; /*為第i個字元編碼分配空間*/
strcpy(hc[i], &cd[start]); /*將求得的編碼從臨時空間cd複製到hc的當前行中*/
}delete cd; /*釋放臨時空間*/
}
資料結構 哈夫曼樹 哈夫曼編碼
哈夫曼樹又稱最優樹 二叉樹 是一類帶權路徑最短的樹。構造這種樹的演算法最早是由哈夫曼 huffman 1952年提出,這種樹在資訊檢索中很有用。結點之間的路徑長度 從乙個結點到另乙個結點之間的分支數目。樹的路徑長度 從樹的根到樹中每乙個結點的路徑長度之和。結點的帶權路徑長度 從該結點到樹根之間的路徑...
哈夫曼編碼 哈夫曼樹 (資料結構)
哈夫曼編碼,又稱霍夫曼編碼,是一種編碼方式,哈夫曼編碼是可變字長編碼 vlc 的一種。huffman於1952年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做huffman編碼 有時也稱為霍夫曼編碼 include include inc...
資料結構 哈夫曼樹與哈夫曼編碼
include pch.h include 哈夫曼樹類huffmantree的定義 huffman樹結點類treenode宣告 template class t class huffmannode 建構函式 huffmannode getleft void const void setleft hu...