1. 引言
最優二叉樹是帶權路徑長度最短的二叉樹。根據結點的個數,權值的不同,最優二叉樹的形狀也各不相同。它們的共同點是:帶權值的結點都是葉子結點。權值越小的結點,其到根結點的路徑越長。構造最優二叉樹的方法如下:
(1) 將每個帶有權值的結點作為一棵僅有根結點的二叉樹,樹的權值為結點的權值。
(2) 將其中兩棵權值最小的樹組成一棵新的二叉樹,新樹的權值為兩棵樹的權值之和。
(3) 重複(2),直到所有的結點都在一棵二叉樹上。這棵二叉樹就是最優二叉樹。
最優二叉樹除了葉子結點就是度為2的結點,沒有度為1的結點。這樣才使得樹的帶權路徑長度最短。根據二叉樹的性質3,最優二叉樹的結點數為葉子數的2倍減1。
2. 赫夫曼編碼
#include "ds.h"
typedef struct
htnode, *huffmantree; // 動態分配陣列儲存赫夫曼樹
typedef char** huffmancode; // 動態分配陣列儲存赫夫曼編碼表
// 返回i個結點中權值最小的樹的根結點序號,函式select()呼叫
int min(huffmantree t, int i)
} t[flag].parent = 1; // 給選中的根結點的雙親賦1,避免第2次查詢該結點
return flag;
}// 在i個結點中選擇2個權值最小的樹的根結點序號,s1為其中序號小的那個
void select(huffmantree t, int i, int &s1, int &s2)
}#ifdef algo1
// w存放n個字元的權值(均》0),構造赫夫曼樹ht,並求出n個字元的赫夫曼編碼hc
void huffmancoding(huffmantree &ht,huffmancode &hc,int *w,int n) // 演算法6.12
m = 2 * n - 1;
ht = (huffmantree)malloc(sizeof(htnode) * (m + 1)); // 0號單元未用
for (p = ht+1,i=1; i <= n; ++i, ++p, ++w)
for (; i <= m; ++i, ++p)
(*p).parent = 0;
// 建赫夫曼樹
// 在ht[1~i-1]中選擇parent為0且weight最小的兩個結點,其序號分別為s1和s2
for (i = n + 1; i <= m; ++i)
// 從葉子到根逆向求每個字元的赫夫曼編碼
hc = (huffmancode)malloc((n+1)*sizeof(char*));
// 分配n個字元編碼的頭指標向量([0]不用)
cd = (char*)malloc(n*sizeof(char)); // 分配求編碼的工作空間
cd[n-1] = '\0'; // 編碼結束符
// 逐個字元求赫夫曼編碼
for (i = 1; i <= n; i++)
hc[i] = (char*)malloc((n-start)*sizeof(char));
// 為第i個字元編碼分配空間
strcpy(hc[i],&cd[start]); // 從cd複製編碼(串)到hc }
free(cd); // 釋放工作空間 }
#else
void huffmancoding(huffmantree &ht,huffmancode &hc,int *w,int n) // 前半部分為演算法6.12
for(;i<=m;++i,++p)
(*p).parent=0;
for(i=n+1;i<=m;++i) // 建赫夫曼樹
// 以下為演算法6.13,無棧非遞迴遍歷赫夫曼樹,求赫夫曼編碼,以上同演算法6.12
hc=(huffmancode)malloc((n+1)*sizeof(char*));
// 分配n個字元編碼的頭指標向量([0]不用)
cd=(char*)malloc(n*sizeof(char)); // 分配求編碼的工作空間
c=m;
cdlen=0;
for(i=1;i<=m;++i)
ht[i].weight=0; // 遍歷赫夫曼樹時用作結點狀態標誌
while(c)
else if(ht[c].rchild==0)
}else if(ht[c].weight==1)
}else
}free(cd);
}#endif
int main()
資料結構 赫夫曼樹(最優二叉村)
赫夫曼樹,也稱最優二叉樹。樹的帶權路徑長度為樹中所有葉子節點的帶權路徑長度之和最短。書上舉例多if條件巢狀判斷,但由於各個條件出現的概率不一樣,優化條件排布的先生順序,程式執行的總路徑長度也不一樣,將高概率的條件放在前面,就使總長度最小。赫夫曼樹的原理就是這樣,在程式優化時,可以使用這個原理。發散 ...
構造赫夫曼樹(最優二叉樹)
例如,有權值分別為 5 10 15 20 25 40的結點,根據以上演算法構造出乙個哈夫曼樹。取這六個樹中最小的兩個樹5 10連成乙個二叉樹,其權值為15 此時森林裡的樹變為15 5 10 15 20 25 40。取這五個樹中最小的兩個樹 15 5 10 15 構成乙個新的二叉樹30 5 10 15...
資料結構學習筆記 二叉樹
樹,非線性表結構 樹有三個概念 高度從下向上數,起點是0 深度從上向下數,起點是0 層數從上向下數,起點是1 每個節點最多兩個叉 有兩種特殊二叉樹 滿二叉樹,除了葉子節點,每個節點都有左右兩個子節點 完全二叉樹,葉子節點都在最底下兩層,最後一層葉子節點都靠左排列,且除了最後一層,其它層節點個數都達到...