標籤:代碼實現 image i++ 介紹 string main 移動 content ...
一、 什麼是哈夫曼樹
是一種帶權路徑長度最短的二叉樹,也稱最優二叉樹
帶權路徑長度:WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln)
N個權值Wi(i=1,2,...n)構成一棵有N個葉結點的二叉樹。對應的葉結點的路徑長度為Li(i=1,2,...n)。
二、 建立哈夫曼樹
已知的一組葉子的權值w1,w2,w3……wn;
①首先把 n 個葉子結點看做 n 棵樹(僅有一個結點的二叉樹)。把它們看做一個森林。
②在森林中把權值最小和次小的兩棵樹合并成一棵樹。該樹根結點的權值是兩棵子樹權值之和。
這時森林中還有 n-1 棵樹。
③反覆第②步直到森林中僅僅有一棵為止。此樹就是哈夫曼樹。
現給一組 (n=4) 詳細的權值: 2 , 4 , 5 。 8 ,下邊是構造詳細過程:
n 個葉子構成的哈夫曼樹其帶權路徑長度是唯一的。但樹形是不唯一的。由於將森林中兩棵權值最小和次小的子棵合并時,哪棵做左子樹,哪棵做右子樹並不嚴格限制。
三、 哈夫曼樹的應用
a) 哈夫曼編碼
利用哈夫曼樹求得的用於通訊的二進位編碼稱為哈夫曼編碼。樹中從根到每一個葉子節點都有一條路徑,對路徑上的各分支約定指向左子樹的分支表示”0”碼,指向右子樹的分支表示“1”碼。取每條路徑上的“0”或“1”的序列作為各個葉子節點相應的字元編碼,即是哈夫曼編碼。
當中A,B,C,D相應的哈夫曼編碼分別為:111。10,110。0
b) 二路歸併排序
如果如今有n個已經排序的檔案{d1,d2,….dn}。每一個檔案包括的記錄個數相應是{w1,w2,w3…..wn};能夠採用兩兩合并的方法,把所有檔案的記錄合并到一個大檔案裡,使得這個檔案裡的記錄所有排序。
問:採用什麼合并次序才幹使移動個數最少?
答:依照哈夫曼樹的結構從外部結點到根節點逐層進行合并,一定是一種最佳的合并順序。
四、 哈夫曼樹的代碼實現
用java實現的哈夫曼樹
public class Huffman {public static void main(String[] args){Huffman huffman = new Huffman();int[] a = {2,3,5,7,11,13,17,19,23,29,31,37,41};System.out.println(a.length);HfTree tree = huffman.createHfTree(a.length , a);System.out.println("ht ww parent lchild rchild ");for(int i=0;i<tree.node.length;i++){System.out.println(i +" "+ tree.node[i].ww +" "+ tree.node[i].parent +" "+ tree.node[i].lchild +" "+ tree.node[i].rchild);}}private static int MAXINT=10000;public HfTree createHfTree(int m , int a[]){HfTree hfTree = new HfTree(m);/*初始化哈夫曼樹*/for(int i=0;i<2*m-1;i++){hfTree.node[i].lchild = -1;hfTree.node[i].rchild = -1;hfTree.node[i].parent = -1;if(i<m){hfTree.node[i].ww = a[i];}}/*開始產生哈夫曼樹*/for(int i=0; i<m-1;i++){int x1 = 0;int x2 = 0;int m1 = MAXINT;int m2 = MAXINT;for(int j=0; j<m+i;j++){if(hfTree.node[j].ww < m1 && hfTree.node[j].parent == -1){m2 = m1;x2 = x1;m1 = hfTree.node[j].ww;x1 = j;}else if(hfTree.node[j].ww < m2 && hfTree.node[j].parent == -1){m2 = hfTree.node[j].ww;x2 = j;}}hfTree.node[x1].parent = m+i;hfTree.node[x2].parent = m+i;hfTree.node[m+i].ww = m1+m2;hfTree.node[m+i].lchild = x1;hfTree.node[m+i].rchild = x2;}hfTree.root = 2*m-2;return hfTree;}}class HfNode{public int ww;public int parent;public int lchild;public int rchild;} class HfTree{ public HfNode[] node; public int root; public int m; HfTree(int m){ this.m = m; this.node = new HfNode[2*m-1];//初始化對象數組是必須每一個對象都建立 for(int i=0;i<2*m-1;i++){ node[i] = new HfNode(); } } }
哈夫曼樹的介紹 ---java實現