1. 程式人生 > >有趣的赫夫曼樹

有趣的赫夫曼樹

bcd 根節點 數字 sum obj 基本 重復 adf 表示

美國有個數學家叫赫夫曼,60年前他根據數據的使用概率,發明了一個二叉樹叫赫夫曼樹。 這個赫夫曼樹被用在了數據壓縮上,被稱為赫夫曼編碼,這是後來壓縮的基礎。 他解決的問題主要思想是:根據元素出現的概率,獲得最優解。 舉例如下: 學生考試成績出來後,會根據考試成績分等級,極優秀,優秀,中等,及格,不及格。如果我們按照普通邏輯進行判斷時,通常是:
    if (Score < 60) {
        printf("不及格");
    } else if (Score < 70) {
        printf("及格");
    } else if (Score < 80) {
        printf("中等");
    } else if (Score < 90) {
        printf("優秀");
    } else if (Score < 100) {
        printf("極優秀");
    }
但是按照分數的分布概率,優秀:30%,中等:40%,及格:15%,極優秀:10%,不及格:5% 如果先判斷優秀,中等,再判斷極優秀,極優秀,不及格,則可以提高很多效率。 赫夫曼樹就是根據概率來生成的二叉樹。 轉換成二叉樹區別如下: 技術分享圖片 從根節點出發,遍歷每一個葉子節點,是的到達節點時走的鏈接樹乘以節點(nodeLinkNum * weight)對應的權重之和最小 如: sum = 1*5+2*15+3*40+4*30+4*10 顯然,左圖和右圖總和不一樣,左圖的和大於右圖. 那給你一組數字,怎麽構造一個赫夫曼樹呢? 1.先把所有的數據節點,從小到大依次排列,成為一個有序列表 2.取出前面兩個節點,讓這兩個節點的權重數據相加得到一個和,令這個和為根節點,這個兩個節點的小的為其左孩子,大的為其右孩子 3.令這個和節點替換掉前面的兩個節點,並重新排序,生成一個有序列表 4.不斷重復第二步,第三步。直到所有的節點都被用完,得到一個排序結果,此時生成的二叉樹,就是赫夫曼樹。 技術分享圖片
赫夫曼樹的實際應用:壓縮數據 數據在計算機的表示形式是0,1,那麽一串字符串的表示是怎麽樣的呢 例如ABCDEF編碼如下: 技術分享圖片 那麽要表示字符串“BADCADFEED”的二進制為:“001000011010000011101100100011”。 但是ABCDEF做為基本字符,在這串字符串中的出現概率是不一樣的,那麽我們是否可以以概率做為字符權重,對字符生成赫夫曼樹呢 假設六個字母的頻率為A 27,B 8,C 15,D15,E 30,F 5,合起來正好是100%。那就意味著,我們完全可以重新按照赫夫曼樹來規劃它們。 技術分享圖片 將權值左分支改為0,右分支改為1後的赫夫曼樹。 根據重新編碼後為: 1001010010101001000111100(共25個字符) 而原來的字符編碼為: “001000011010000011101100100011”(共30個字符) 壓縮了近17%
解壓時,按照同樣的規則,還原原字符串。

有趣的赫夫曼樹