009-數據結構-樹形結構-哈夫曼樹[霍夫曼樹]

1、概述

Huffman Tree,中文名是哈夫曼樹或霍夫曼樹,它是最優二叉樹。html

定義:給定n個權值做爲n個葉子結點,構造一棵二叉樹,若樹的帶權路徑長度達到最小,則這棵樹被稱爲哈夫曼樹。java

  

1.一、幾個概念

(01) 路徑和路徑長度
定義:在一棵樹中,從一個結點往下能夠達到的孩子或孫子結點之間的通路,稱爲路徑。通路中分支的數目稱爲路徑長度。若規定根結點的層數爲1,則從根結點到第L層結點的路徑長度爲L-1。
例子:100和80的路徑長度是1,50和30的路徑長度是2,20和10的路徑長度是3。git

(02) 結點的權及帶權路徑長度
定義:若將樹中結點賦給一個有着某種含義的數值,則這個數值稱爲該結點的權。結點的帶權路徑長度爲:從根結點到該結點之間的路徑長度與該結點的權的乘積。
例子:節點20的路徑長度是3,它的帶權路徑長度= 路徑長度 * 權 = 3 * 20 = 60。github

(03) 樹的帶權路徑長度
定義:樹的帶權路徑長度規定爲全部葉子結點的帶權路徑長度之和,記爲WPL。
例子:示例中,樹的WPL= 1*100 + 2*80 + 3*20 + 3*10 = 100 + 160 + 60 + 30 = 350。spa

示例3d

  

上面的兩棵樹都是以{10, 20, 50, 100}爲葉子節點的樹。
  左邊的樹WPL=2*10 + 2*20 + 2*50 + 2*100 = 360
  右邊的樹WPL=350htm

左邊的樹WPL > 右邊的樹的WPL。你也能夠計算除上面兩種示例以外的狀況,但實際上右邊的樹就是{10,20,50,100}對應的哈夫曼樹。blog

2、哈夫曼樹的構造

假設有n個權值,則構造出的哈夫曼樹有n個葉子結點。 n個權值分別設爲 w一、w二、…、wn,哈夫曼樹的構造規則爲:get

  1. 將w一、w二、…,wn當作是有n 棵樹的森林(每棵樹僅有一個結點);
  2. 在森林中選出根結點的權值最小的兩棵樹進行合併,做爲一棵新樹的左、右子樹,且新樹的根結點權值爲其左、右子樹根結點權值之和;
  3. 從森林中刪除選取的兩棵樹,並將新樹加入森林;
  4. 重複(02)、(03)步,直到森林中只剩一棵樹爲止,該樹即爲所求得的哈夫曼樹。it

以{5,6,7,8,15}爲例,來構造一棵哈夫曼樹。

  

第1步:建立森林,森林包括5棵樹,這5棵樹的權值分別是5,6,7,8,15。
第2步:在森林中,選擇根節點權值最小的兩棵樹(5和6)來進行合併,將它們做爲一顆新樹的左右孩子(誰左誰右可有可無,這裏,咱們選擇較小的做爲左孩子),而且新樹的權值是左右孩子的權值之和。即,新樹的權值是11。 而後,將"樹5"和"樹6"從森林中刪除,並將新的樹(樹11)添加到森林中。
第3步:在森林中,選擇根節點權值最小的兩棵樹(7和8)來進行合併。獲得的新樹的權值是15。 而後,將"樹7"和"樹8"從森林中刪除,並將新的樹(樹15)添加到森林中。
第4步:在森林中,選擇根節點權值最小的兩棵樹(11和15)來進行合併。獲得的新樹的權值是26。 而後,將"樹11"和"樹15"從森林中刪除,並將新的樹(樹26)添加到森林中。
第5步:在森林中,選擇根節點權值最小的兩棵樹(15和26)來進行合併。獲得的新樹的權值是41。 而後,將"樹15"和"樹26"從森林中刪除,並將新的樹(樹41)添加到森林中。
此時,森林中只有一棵樹(樹41)。這棵樹就是咱們須要的哈夫曼樹!

 

代碼地址:地址 中的data-004-tree中 huffman

 

參看地址:

  http://www.cnblogs.com/skywang12345/p/3706833.html 

 

 

 

 

 

 

 

 

 

 

相關文章
相關標籤/搜索