一、基本概念
1、赫夫曼(huffman)樹又稱最優二叉樹或最優搜尋樹,是一種帶權路徑長度最短的二叉樹。在許多應用中,常常賦給樹中結點乙個有某種意義的實數,稱此實數為該結點的權。從樹根結點到該結點之間的路徑長度與該結點上權的乘積稱為結點的帶權路徑長度(wpl),樹中所有葉子結點的帶權路徑長度之和稱為該樹的帶權路徑長度,通常記為:
2、兩結點間的路徑:從一結點到另一結點所經過的結點序列;路徑長度:從根結點到相應結點路徑上的分支數目;樹的路徑長度:從根到每一結點的路徑長度之和。
3、深度為k,結點數為n的二叉樹,當且僅當每個結點的編號都與相同深度的滿二叉樹中從1到n的結點一一對應時,稱為完全二叉樹。在結點數目相同的二叉樹中完全二叉樹是路徑長度最短的二叉樹。
4、wpl最小的二叉樹是最優二叉樹(huffman 樹)。
5、赫夫曼(huffman)樹的特徵
① 當葉子上的權值均相同時,完全二叉樹一定是最優二叉樹。否則完全二叉樹不一定是最優二叉樹。
② 在最優二叉樹中,權值越大的葉子離根越近。
③ 最優二叉樹的形態不唯一,但wpl最小。
如上圖中,只有(d)才是赫夫曼樹。其中,圓圍中的數值代表權值。
二、演算法思想
(1) 以權值分別為w1,w2...wn的n各結點,構成n棵二叉樹t1,t2,...tn並組成森林f=,其中每棵二叉樹 ti僅有乙個權值為 wi的根結點;
(2) 在f中選取兩棵根結點權值最小的樹作為左右子樹構造一棵新二叉樹,並且置新二叉樹根結點權值為左右子樹上根結點的權值之和(根結點的權值=左右孩子權值之和,葉結點的權值= wi)
(3) 從f中刪除這兩棵二叉樹,同時將新二叉樹加入到f中;
(4) 重複(2)、(3)直到f中只含一棵二叉樹為止,這棵二叉樹就是huffman樹。
三、演算法描述
①huffman樹結構陣列形式
struct node
②初始化,將2*n-1個結點lchild=rchild=parent=-1;cs=0;
再將前n個點權值放入val;
③從n+1到2*n-1個結點開始迴圈i
每次迴圈在未被使用過的結點中找出最小的兩個結點s1,s2合併,合併的方法具體如下
huf[i].lchild=s1;
huf[i].rchild=s2;
huf[s1].parent=huf[s2].parent=i;
huf[i].val=huf[s1].val+huf[s2].val;
這樣就完成了huffman樹的陣列建立
④層數的獲取
這裡我用了while迴圈不斷的向上只要huf[i].parent!=-1就將層數++,每個點找一邊到最後就能算出wpl
具體**如下:
#include #include using namespace std;
struct node
;int a[1010];
node huf[2010];
int s1=0,s2=0;
void select(int n)
for (int i=0;iif (huf[i].parent==-1&&min>=huf[i].val) s1=i,min=huf[i].val;
min=9999999;
for (int i=0;iif (huf[i].parent==-1&&min>=huf[i].val)
}void bin(int n)
}int main()
bin(n);
for (int i=0;iint p=i;
while (huf[p].parent!=-1)
res+=huf[i].cs*huf[i].val;
// cout << huf[i].cs << " " << huf[i].val << endl;
}cout << res << endl;
}
關於層數實現我想可以直接在建樹的時候就可以算出,
等有空下次補充
C 實現Huffman最優二叉樹
huffman最優二叉樹對於壓縮編碼具有重要作用 cpp huffman樹 最優二叉樹 include include include using namespace std 定義節點結構體型別 typedef struct node node node 存放節點的向量 vector nodes 存...
huffman樹(最優二叉樹 和huffman編碼
在許多實際應用中,數中結點常常被賦予乙個表示某種意義的數值,稱為該結點的權。從樹根結點到任意結點的路徑長度 經過的邊數 與該結點上權值的乘積稱為該結點的帶權路徑長度。數中所有葉結點的帶權路徑長度之和稱為該樹的帶權路徑長度 特點 1.每個初始結點最終都成為葉結點,且權值越小的結點到根節點的路徑長度越大...
最優二叉樹
include include includetypedef struct huffmantree typedef char huffmancode 赫夫曼編碼 void selectnode huffmantree ht,int n,int bt1,int bt2 從1 i 1個結點選擇paren...