帶權樹存儲
① 權值為2,3,4,5,6構成的哈夫曼樹,帶權路徑長度為
假設有n個權值,則構造出的哈夫曼樹有n個葉子結點。 n個權值分別設為 w1、w2、…、wn,則哈夫曼樹的構造規則為:
(1) 將w1、w2、…,wn看成是有n 棵樹的森林(每棵樹僅有一個結點);
(2) 在森林中選出兩個根結點的權值最小的樹合並,作為一棵新樹的左、右子樹,且新樹的根結手敏點權值為其左、右子樹根結點權值之和;
(3)從森林中刪除選取的兩棵樹,並將新樹加入森林;
(4)重復(2)、(3)步,直到森林中只剩一棵樹為止,該樹即為所求得的哈夫曼樹。
(1)帶權樹存儲擴展閱讀:
在一棵樹中,從一個結點往下可以達到的孩子或孫子結點之間的通路,稱為路徑。通路中分支的數目稱為路徑長度。若規定根結點的層數為1,則從根結點到第L層結點的路徑長度為L-1。
若將樹核薯斗中結點賦給一個有著某種含義的數值,則這個數值稱為該結點的權。結點的帶權路徑長度為:從根結點到該結點之間的路徑長度與該結點的權的乘積。
實現哈夫曼編碼的方式主要是創建一個二叉樹和其節點。這些樹的節點可以存儲在數組里,數組的大小為符號數的大小n,而節點分改磨別是終端節點(葉節點)與非終端節點(內部節點)。
② 什麼是帶權最優二元樹
一毀運沖棵帶權二元樹的代價就是樹中所有根結點權之和.代價最小的帶權二元樹稱為最優二元樹.問題轉化為求最優帶權二元樹.
那麼,什麼是最優帶權二元樹呢?
最優二叉樹,又稱哈夫曼樹,是一類帶權路徑長度最短的樹,有著廣泛的應用.
我們首先給出路徑和路徑長度的概念.從樹中一個結點到另一個結點之間的分支構成這兩個結點之間的路徑,路徑上的分支數目稱做路徑長度.樹的路徑長度是從樹根到每一結點的路徑長度之和.這種路徑長度最短的二叉樹是.
若將上述概念推廣到一般情況,考慮帶權的結點.結點的帶權路徑長度為從該結點樹根之間的路徑長度與結點上權的乘積.樹的帶權路徑長度為樹中所有葉子結點的帶悄坦路徑長度之和,通常記作
WPL=∑W(k)L(k) k=1...n
假設有n個權值W(1),W(2),.,W(n),試構造一棵有n個葉子結點的二叉樹,每個葉子結點帶權為W(k),則其中帶權路徑長度WPL最小的二叉樹稱做最優二又樹或哈纖殲夫顯樹.
③ 求帶權4,5,7,10,11,12,15的最優二叉樹並計算它的權
帶權二叉樹是指一種用來表示帶權信息的二叉樹,常用於數據壓縮和信息編碼。
建立帶權二叉樹的一種方法是採用貪心演算法,具體流程如下:
將所有的帶權信息按權值從小到大排序。纖敬
取出權值最小兄豎敏的兩個信息,將它們合並成一個新的信息,新信息的權值為兩個信息的權值之和。
將新信息加入羨枝到剩餘的信息中,繼續執行步驟2直到所有的信息都合並為一個。
合並出的最後一個信息即為帶權二叉樹的根節點。
根據上述流程,我們可以建立帶權4,5,7,10,11,12,15的最優二叉樹。首先將所有的信息按權值從小到大排序得到4,5,7,10,11,12,15。然後依次合並,得到如下的二叉樹:
Copy code
11
/
4 7
/
5 10
/
12 15
該二叉樹的權值為11+4+7+5+10+12+15=64。
注意:這里只是一種建立帶權二叉樹的方法,並不一定是最優解。
④ 帶權路徑長度是什麼
帶權路徑長度也就是樹的帶權路徑長度,樹的路徑長度是從樹根到樹中每一結點的路徑長度之和。在結點數目相同的二叉樹中,完全二叉樹的路徑粗兄吵長度最短。
結點的權:在一些應用中,賦予樹中結點的塵衡一個有某種意義的實數。
結點的帶權路徑長度:結點到樹根之間的路徑長度與該結點上權的乘積。
特性:
若將樹中結點賦給一個有著某種含義的數值,則這個數值稱為該結點的權。結點的帶權路徑岩侍長度為:從根結點到該結點之間的路徑長度與該結點的權的乘積。
實現哈夫曼編碼的方式主要是創建一個二叉樹和其節點。這些樹的節點可以存儲在數組里,數組的大小為符號數的大小n,而節點分別是終端節點(葉節點)與非終端節點(內部節點)。
⑤ 初步認識哈夫曼樹
7.哈夫曼數的基本概念:
(1)路徑:模帶由一結點到另一結或碼派點間的分支所構成
(2)路徑長度:路徑上的分支數目a→d的路徑長度= 2
(3)樹的路徑長度:從樹根到每一結點的路徑長度之和。 例圖:10
(4)權:賦予某個實體的一個量,是對實體的屬性的數值化描述。若樹的結點帶有權值,即為帶權樹。
(5)結點的帶權路徑長度:結點到根的路徑長度與結點上權值的乘積d的帶權路徑長度=7*2=14
(6)樹的帶權路徑長度:樹中所有葉子結點的帶權路徑長度之和。例圖:2*7+2*5+2*2+2*4=36
(7)赫夫曼樹(Huffman):最優二叉樹,帶權路徑長度最小的樹
哈夫曼樹的特點
–權值大的結點到根結點的路徑長度短;
–權值小的結點到根結點的路徑長度長。
Ø哈夫曼編碼樹中沒有度為1的結點;
Ø若給定n個權值(n個葉子結點),則哈夫曼樹的總結點數為 2n-1;
Ø哈夫曼樹的高度不超過n。
哈夫曼數的構造演算法:
哈夫曼編碼:
v前綴編碼:任一字元的編碼都不是另一字元編碼的前綴。
如:字元a、b、c、d的編碼分別為0、1、01、10,則a的編碼是c的編碼的前綴,b的編碼是d編碼的前綴,該編碼不是前綴編碼。
在解碼時,對於01011011的解碼結果將不唯一。
v哈夫曼編碼
對一棵具有n個葉子的哈夫曼樹,對每個左分支賦予0,右分支賦予1,則從根到每個葉子的路徑上,分別構成一個二進制串,該二進制串稱為哈夫曼編碼。
進行哈夫曼編碼,先建哈夫曼樹。
哈夫曼編碼是前綴編碼,且是最優前綴編碼衫賀。
⑥ 最優二叉樹
最優二叉樹概念
.樹的路徑長度 樹的路徑長度是從樹根到樹中每一結點的路徑長度之和 在結點數目相同的二叉樹中 完全二叉樹的路徑長度最短
.樹的帶權路徑長度(Weighted Path Length of Tree 簡記為WPL) 結點的權 在一些應用中 賦予樹中結點的一個有某種意義的實數 結點的帶權路徑長度 結點到樹根之間的路徑長度與該結點上權的乘積 樹的帶權路徑長度(Weighted Path Length of Tree) 定義為樹中所有葉結點的帶權路徑長度之和 通常記為 其中 n表示葉子結點的數目w i和l i分別表示葉結點k i的權值和根到結點ki之間的路徑長度 樹的帶權路徑長度亦稱為樹的代價
.最優二叉樹或哈夫曼樹 在權為wl w … wn的n個葉子所乎困構成的所有二叉樹中 帶權路徑長度最小(即代價最小)的二叉樹稱為最優二叉樹或哈夫曼樹 【例】給定 個葉子結點a b c和d 分別帶權 和 構造如下圖所示的三棵二叉樹(還有許多棵) 它們的帶權路徑長度分別為 (a)WPL= * + * + * + * = (b)WPL= * + * + * + * = (c)WPL= * + * + * + * = 其中(c)樹的WPL最小 可以驗證 它就是哈夫曼樹
注意 ① 葉子上的權值均相同時 完全二叉樹一定是最優二叉樹 否則完全二叉樹不一定是最優二叉樹 ② 最優二叉樹中 權越大的葉子離根越近 ③ 最優二叉樹的形態不唯一 WPL最小
構造最優二叉樹
.哈夫曼演算法 哈夫曼首先給出了對於給定的葉子數目及其權值構造最優二叉樹的方法 故稱其為哈夫曼演算法 其基本思想是 ( )根據給定的n個權值w l w … wn構成n棵二叉樹的森林F={T T … T n} 其中每棵二叉樹T i中都只有一個權值為w i的根結點 其左右子樹均空 ( )在森林F中選出兩棵根結點權值最小的樹(當這樣的樹不止兩棵樹時 可以從中任選兩棵) 將這兩棵樹合並成一棵新樹 為了保證新樹仍是二叉樹 需要增加一個新結點作為新樹的根 並將所選的兩棵樹的根分別作為新根的左右孩子(誰左 誰右無關緊要) 將這兩個孩子的權值之和作為新樹根的權值 ( )對新的森林F重復( ) 直到森林F中只剩下一棵樹為止 這棵樹便是哈夫曼樹 用哈夫曼演算法構造哈夫曼樹的過程見【動畫演示】 注意 ① 初始森林中的n棵二叉樹 每棵樹有一個孤立的結點 它們既是根 又是葉子② n個葉子的哈夫曼樹要經過n 次合並 產生n 個新結點 最終求得的哈夫曼樹 *** 有 n 個結點 ③ 哈夫曼樹是嚴格的二叉樹 沒有度數為 的分支結點 .哈夫曼樹的存儲結構及哈夫曼演算法的實現 ( ) 哈夫曼樹的存儲結構 用一個大小為 n 的向量來存儲哈夫曼樹中的結點 其存儲結構為 #define n //葉子數目 #define m *n //樹中結點總數 typedef struct { //結點類型 float weight //權值 不妨設權值均大於零 int lchild rchild parent //左右孩歲橡念子及雙親指針 }HTNode typedef HTNode HuffmanTree[m] //HuffmanTree是向量類型 注意 因為C語言數組的下界為 故用 表示空指針 樹中某結點的lchild rchild和parent不等於 時 它們分別是該結點的左 右孩子和雙親結點在向量中的下標 這里設置parent域有兩個作用 其一是使查找某結點的雙親變得簡單 其二是可通過判定parent的值是否為 來區分根與非根結點
( )哈夫曼演算法的簡要描述 在上述存儲結構上實現的哈夫曼演算法可如跡大致描述為(設T的類型為HuffmanTree) ( )初始化 將T[ ..m ]中 n 個結點里的三個指針均置為空(即置為 ) 權值置為 ( )輸人 讀人n個葉子的權值存於向量的前n個分量(即T[ ..n ])中 它們是初始森林中n個孤立的根結點上的權值 ( )合並 對森林中的樹共進行n 次合並 所產生的新結點依次放人向量T的第i個分量中(n≤i≤m ) 每次合並分兩步 ①在當前森林T[ ..i ]的所有結點中 選取權最小和次小的兩個根結點[p ]和T[p ]作為合並對象 這里 ≤p p ≤i ② 將根為T[p ]和T[p ]的兩棵樹作為左右子樹合並為一棵新的樹 新樹的根是新結點T[i] 具體操作 將T[p ]和T[p ]的parent置為i 將T[i]的lchild和rchild分別置為p 和p 新結點T[i]的權值置為T[p ]和T[p ]的權值之和 注意 合並後T[pl]和T[p ]在當前森林中已不再是根 因為它們的雙親指針均已指向了T[i] 所以下一次合並時不會被選中為合並對象 哈夫曼演算法模擬演示過程【參見動畫模擬】
( )哈夫曼演算法的求精 void CreateHuffmanTree(HuffmanTree T) {//構造哈夫曼樹 T[m ]為其根結點 int i p p InitHuffmanTree(T) //將T初始化 InputWeight(T) //輸入葉子權值至T[ ..n ]的weight域 for(i=n i<m i++){//共進行n 次合並 新結點依次存於T[i]中 SelectMin(T i &p &p ) //在T[ ..i ]中選擇兩個權最小的根結點 其序號分別為p 和p T[p ] parent=T[p ] parent=i TIi] child=p //最小權的根結點是新結點的左孩子 T[j] rchild=p //次小權的根結點是新結點的右孩子 T[i] weight=T[p ] weight+T[p ] weight } // end for }上述演算法中調用的三個函數【參見練習】 【例】以 個權值 為例 執行CreateHuffmanTree求最優二叉樹的過程【參見動畫模擬】
lishixin/Article/program/sjjg/201311/23014
⑦ 數據結構怎麼用以存儲邊(帶權)的一維數組表示圖。
一般在數據山納結構裡面,指針比較吃香。但是,也會用到一維數組和二維數組:比如說,線性表或者鏈表的遍歷,插入元素,刪除元素……而要用到二維數組的就是在需要鄰逗清沒接矩陣的時候啦。
一般來說,程序里,有這樣一種聲明一維數組和二維數組的方法:
typedef struct
{
int *elem;
……
}; //以後就可以用elem[i];(i=0,1,2,…,length) 這就是一維數組啦
typedef struct
{
…正簡…
}matrix[row][column]; //這就是二維數組啦