1. 程式人生 > >哈夫曼樹

哈夫曼樹

hat uri 多個 效率 str hub 所有 huffman 設有

when? what? why? how?

why

為什麽會出現哈夫曼樹?

what

哈夫曼樹有什麽用?

什麽是哈夫曼樹?

哈夫曼樹的特點是啥?

how

如何創建哈夫曼樹?


為什麽會出現哈夫曼樹?

效率!!!

比如一所高中有1000個同學進行了一次考試(總分100),現在需要將每個成績段轉換為優、良、中、合格、不合格(已經知道每個分數段多少人)。

技術分享圖片

當不合格、合格這塊同學比較多時效率比較高,因為大部分人只要比較一次或兩次。如果中高分段人比較多那麽這時候的效率就比較低了因為大部分人需要比較至少 3 次以上。

技術分享圖片

當中間段人比較多時,這個比較方法效率高,大多數人只要比較一到兩次,如果兩端人比較多那麽效率就比較低。

所以,當我們知道每個分數段大概有多少人時,可以將分數段人多的放在頂端減下比較次數,少的放底端。 有這個需求所以 哈夫曼樹出現了....(瞎說的)追求效率最高

什麽是哈夫曼樹?

簡單說WPL最小的二叉樹

了解幾個定義

1.樹的路徑長度

樹的路徑長度是從樹根到樹中每一結點的路徑長度之和。在結點數目相同的二叉樹中,完全二叉樹的路徑長度最短。

2.樹的帶權路徑長度(Weighted Path Length of Tree,簡記為WPL)

結點的權:在一些應用中,賦予樹中結點的一個有某種意義的實數。

結點的帶權路徑長度:結點到樹根之間的路徑長度與該結點上權的乘積。

樹的帶權路徑長度 (Weighted Path Length of Tree):定義為樹中所有葉結點的帶權路徑長度之和,通常記為: WPL=(W1L1+W2

L2+W3L3+...+WnLn)

其中:Wi 和 Li 分別表示葉結點的權值和根到結點之間的路徑長度。
樹的帶權路徑長度亦稱為樹的代價。

哈夫曼樹定義
假設有 n 個權值[W1,W2,....WN],構造有 n 個葉子的二叉樹,每個葉子的權值是 n 個權值之一,這樣的二叉樹可以構造很多個,其中必有一個是帶權路徑長度最小的,這棵二叉樹就稱為最優二叉樹或哈夫曼樹。

哈夫曼樹的特點是啥?

  1. 沒有度為1的結點
  2. n個葉子結點的哈夫曼樹共有2n-1個結點
  3. 哈夫曼樹任意非葉借點的左右樹交換後仍是哈夫曼樹

如何創建哈夫曼樹?

class HuffmanTree {
public static HTNode buildHuffmanTree(HeapHNode heap, int[] data) {
    //構建最小堆
    heap.buildMinHeap(heap, data);
    HTNode node =null;
    int num=heap.size;
    //做heap.size - 1 次合並
    for(int i=1;i<num;i++){
        node=new HTNode();
        //從最小堆中刪除一個結點作為新結點的做左子節點
        node.left=heap.deleteMin(heap);
        //從最小堆中刪除一個結點作為新結點的做右子節點
        node.right=heap.deleteMin(heap);
        node.weight=node.left.weight+node.right.weight;
        //將新結點插入最小堆中
        heap.insert(heap,node);
    }
    //最小堆中的最後一個結點即指向哈夫曼樹的樹根結點
    return heap.deleteMin(heap);
}
}

時間復雜度分析

  1. 構建最小堆 O(N)
  2. 2(N-1)+1個刪除:O(NlogN)
  3. N-1 個插入 :O(NlogN)

所以時間復雜度 O(NlogN)。

結果

數據:100, 34, 67, 78, 98, 55, 44

技術分享圖片

源代碼:https://github.com/rookieLJ/Tree.git

TestHuffmanTree.java

總結

參考
數據結構 陳越 何欽銘

哈夫曼樹的創建是用了最小堆。

哈夫曼樹的主要作用

https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fr=aladdin

簡單說為了進行哈夫曼編碼,這樣就可以起到壓縮作用.

在數據通信中,需要將傳送的文字轉換成二進制的字符串,用0,1碼的不同排列來表示字符.例如,需傳送的報文為“AFTER DATA EAR ARE ART AREA”,這裏用到的字符集為“A,E,R,T,F,D”,各字母出現的次數為{8,4,5,3,1,1}.現要求為這些字母設計編碼.要區別6個字母,最簡單的二進制編碼方式是等長編碼,固定采用3位二進制,可分別用000、001、010、011、100、101對“A,E,R,T,F,D”進行編碼發送,當對方接收報文時再按照三位一分進行譯碼.顯然編碼的長度取決報文中不同字符的個數.若報文中可能出現26個不同字符,則固定編碼長度為5.然而,傳送報文時總是希望總長度盡可能短.在實際應用中,各個字符的出現頻度或使用次數是不相同的,如A、B、C的使用頻率遠遠高於X、Y、Z,自然會想到設計編碼時,讓使用頻率高的用短碼,使用頻率低的用長碼,以優化整個報文編碼.

哈夫曼樹