1、路徑:從樹中乙個結點到另乙個結點之間的分支構成這兩個結點之間的路徑。
2、路徑長度:路徑上的分支數目稱作路徑長度。
3、樹的路徑長度:從樹根到每一結點的路徑長度之和。
4、權:賦予某個實體的乙個量,是對實體的某個或某些屬性的數值化描述。
5、結點的帶權路徑長度:從該結點到樹根之間的路徑長度與結點上權的乘積。
6、樹的帶權路徑長度:樹中所有葉子結點的帶權路徑長度之和,通常記為:
7、哈夫曼樹:假設有m個權值,可以構造一棵含n個葉子結點的二叉樹,每個葉子結點的權為wi,則其中帶權路徑長度wpl最小的二叉樹稱為最優二叉樹或哈夫曼樹。
注意:
(1)完全二叉樹不一定是哈夫曼樹;
(2)權值越大的結點越靠近根結點;
(3)哈夫曼樹不唯一,但其樹的帶權路徑長度一定相等;
哈夫曼樹結點結構:
哈夫曼樹的儲存表示
typedef
struct
htnode,
*huffmantree;
//動態分配陣列儲存哈夫曼樹
哈夫曼樹結點個數:
例題:已知w=(5,29,7,8,14,23,3,11),生成一棵哈夫曼樹,計算樹的帶權路徑長度。並給出其構造過程中儲存結構ht的初始狀態和終結狀態。
【演算法描述】
void
createht
(huffmantree &ht,
int n)
.lchild=0;
ht[i}
.rchild=0;
}for
(i=1
;i<=n;
++i)
//輸入前n個結點的權值
for(i=n+
1;i<=m;
++i)
.parent=i;
ht[s2}
.parent=i;
//得到新結點i,從森林中刪除s1,s2,將s1和s2的雙親域由0改為1
ht[i]
.lchild=s1;
//s1作為i的左結點
ht[i}
.rchild=s2;
//s2作為i的右結點
ht[i]
.weight=ht[s1]
.weight+ht[s2]
.weight;
//i的權值為左右孩子權值之和
}
將樹的左分支標記為0,右分支標記為1;(左0右1)權哈夫曼編碼
50 0 0 0
30 0 0 1
110 0 1
230 1
291 0
141 1 1
71 1 0 0
81 1 0 1
要求:1、從鍵盤輸入n, 以及n個字元的概率。
例如:已知某系統在通訊聯絡中只可能出現n種字元,其概率分別為 0.05, 0.29, 0.07, 0.08, 0.14, 0.23, 0.03, 0.11,試設計哈夫曼編碼建立哈夫曼樹。
2、用順序儲存。
#include
using
namespace std;
//哈夫曼樹的儲存結構
typedef
struct
htnode,
*huffmantree;
//封裝兩個最小結點
typedef
struct
min;
//選擇雙親為0且結點權值最小的兩個結點
min select
(huffmantree ht,
int n)
}for
(int i =
1; i <= n; i++)}
code.s1 = s1;
code.s2 = s2;
return code;
}//創造哈夫曼樹
void
createhuffmantree
(huffmantree &ht,
int num)
cout <<
"請輸入每個葉子結點的權值:"
<< endl;
for(
int i =
1; i <= num; i++
)for
(int i = num +
1; i <= m; i++
)//輸出哈夫曼樹儲存結構的末態
for(
int i =
1; i <= m; i++)}
intmain()
哈夫曼樹的建立以及哈夫曼編碼
主要源 如下 include include define max num 105 typedef struct htnode,htree void selecttwomin htree ht,int n,int s1,int s2 ht s1 visited 1 將最小的頻率對應的結點標記為已被訪...
哈夫曼樹的建立
include include using namespace std typedef struct node tree void find tree t,int s1,int s2,int n int creat tree t,int n int s1,s2 先找了兩個值,然後一直比較找最小,也可...
哈夫曼樹建立和哈夫曼碼生成
直接上 htree.h typedef struct htreenode htreenode main.cpp include include include include htree.h htreenode inithtree int num 初始化哈夫曼樹結點 void getmin htre...