定義:哈夫曼樹又稱最優樹,是一類帶權路徑最短的樹。
結點的帶權路徑:結點所代表的數乘以從根到改結點所經過的路(即改結點所在的深度-1)
樹的帶權路徑(wpl):就是指所有結點帶權路徑和的最小值
那到底什麼叫wpl呢?
舉個栗子:如圖所示的三顆二叉樹,都含有四個葉子結點a,b,c,d,權值分別為7,5,2,4;那麼它們的wpl 分別為多少呢?
很明顯 第三顆樹的wpl 的最小 也就是我們所求的哈夫曼樹
那麼哈夫曼樹到底該怎麼畫呢 ?
這裡為了方便起見,我們先直接把權值代表該葉子結點 給你一組權值 2,4,5,3,該怎麼畫出哈夫曼樹呢?
第一步:這四個葉子初始時呢 是這個樣子滴 (先排個序
第二步: 我們找出權值最小的兩個結點2和3,然後將他們合併
重複第二步: 如果有重複 隨便選(所以最後的樹可能不一樣但是wpl相等) 那這裡我們選第二個5和4 合併
繼續重複 顯然 現在沒得選了 合併
這樣 一顆哈夫曼樹就建立成功了 wpl= 2*2+3*2+4*2+5*2=28
當然 如果在第二步合併的是第乙個5和4 那麼哈夫曼樹為
畫完哈夫曼樹之後 有沒有發現什麼規律?
1)在哈夫曼樹中,權值越大的結點距離根節點就越近。
2)哈夫曼樹是一顆只有度為1和度為2的二叉樹,葉子結點為n個,那麼度為2的結點有n-1個,整棵樹的結點就有2n-1個。
第一步: 考慮哈夫曼樹的結點是什麼型別的呢?
由哈夫曼樹的特點我們知道結點數一共有2n-1個那麼我們可以用一維陣列儲存這些結點,而對於每乙個結點來說,分為四部分,分別存放權值,雙親,左孩子和右孩子;
typedef structhtnode,*nuffmantree;
第二步:建立哈夫曼樹
(1) 初始化
動態申請2n-1個空間,迴圈2n-1次將雙親,左孩子,右孩子置為-1;迴圈n次,將權值賦給結點的weight;
(2)選取與合併
選出還沒有雙親的兩個權值最小的結點 ,將它們合併
(3)刪除與加入
將上一步選出了兩個結點的雙親置更新,新結點的左右孩子更新
(4)重複(2)和(3)n次
**實現
//構造哈夫曼樹
void createnuffmantree(nuffmantree &ht,int w,int n)
for(int i=0;iselect函式 遍歷0~k-1的結點 找出還沒有雙親的權值最小的兩個結點的下標s1,s2
//select 函式 找出沒有雙親結點的兩個位置
void select(nuffmantree ht,int k,int &s1,int &s2)
}}
再來個栗子 權值 2 4 5 3
初始化
本來以為編碼挺難的 其實寫出來 也不難嘛~
既然在上一步我們已經畫好了哈夫曼樹,現在只要對哈夫曼樹加一點點東西就好
我們把左枝置0,右枝置1(當然也可以倒過來 隨心所欲~)
對於上個例子 我們把 2 4 5 3 分別當做字母 a b c d的權值
結果如圖:
這樣就得到了 a b c d 的編碼 a:00 b:10 c:11 d:01
完整**實現:
#include#includeusing namespace std;
typedef structhtnode,*nuffmantree;
int w[101],n;
//select 函式 找出沒有雙親結點的兩個位置
void select(nuffmantree ht,int k,int &s1,int &s2)
}} //構造哈夫曼樹
void createnuffmantree(nuffmantree &ht,int w,int n)
for(int i=0;i>n;
char a[256];
cout>w[i];
createnuffmantree(ht,w,n);//建樹
creathuffmancode(ht,hc,n);//編碼
for(int i=0;i
return 0;
}
資料結構 哈夫曼樹與哈夫曼編碼
1 路徑 由乙個結點到另乙個結點之間的所有分支共同構成。2 路徑長度 結點之間的分支數目。3 樹的路徑長度 從樹的根結點到其他所有結點的路徑長度之和。4 權 賦予某一實體的值。在資料結構中,實體包括結點和邊,所以對應有結點權和邊權。5 結點的帶權路徑長度 結點與樹的根結點之間的路徑長度與結點權的乘積...
資料結構 哈夫曼樹與哈夫曼編碼
include pch.h include 哈夫曼樹類huffmantree的定義 huffman樹結點類treenode宣告 template class t class huffmannode 建構函式 huffmannode getleft void const void setleft hu...
資料結構 哈夫曼樹 哈夫曼編碼
哈夫曼樹又稱最優樹 二叉樹 是一類帶權路徑最短的樹。構造這種樹的演算法最早是由哈夫曼 huffman 1952年提出,這種樹在資訊檢索中很有用。結點之間的路徑長度 從乙個結點到另乙個結點之間的分支數目。樹的路徑長度 從樹的根到樹中每乙個結點的路徑長度之和。結點的帶權路徑長度 從該結點到樹根之間的路徑...