淺談赫夫曼樹及其應用(文件壓縮)

日常生活中經(jīng)常會使用到文件壓縮,但是基本很少有人會問到壓縮是如何實現(xiàn)的。所謂的帜矾,就是把文本重新進行編碼,減少不必要的空間屑柔。目前最新技術在編碼上已經(jīng)很強大屡萤,但是筆者不打算說那些很高深的壓縮技術(其實那些高深的壓縮技術,其實筆者也不懂)掸宛。雖然有很多高深的壓縮技術死陆,但是目前經(jīng)常使用到的壓縮和解壓縮技術都是基于赫夫曼的研究基礎上發(fā)展而來。所以今天就簡單介紹一個最基本的壓縮編碼方法-----赫夫曼編碼唧瘾。

一措译、實例開篇

        if a < 60 {
            b = "不及格"
        }else if a < 70{
            b = "及格"
        }else if a < 80 {
            b = "中等"
        }else if a < 90{
            b = "良好"
        }else {
            b = "優(yōu)秀"
        }

如上代碼是百分制考試的評分標準。粗略看上面的代碼饰序,貌似沒有什么問題瞳遍。但是通常情況來說一個班級的學生成績分布在及格、中等菌羽、良好的相對較多掠械,分布在優(yōu)秀和不及格的相對較少。但是上面的代碼注祖,最開始的邏輯是先判斷是否及格猾蒂,再逐漸向上得到結果。當輸入量很大的時候是晨,算法在效率方面是存在一定問題的肚菠。

假設實際中學生在5個等級上成績分布的概率如下表所示。如果按照上述的代碼邏輯執(zhí)行罩缴,70分以上的成績占總概率的80%蚊逢,但是想判斷出一個70分以上的成績至少需要執(zhí)行3次以上的判斷才能得到結果,顯然是十分不合理的箫章。


成績分布規(guī)律

如果能依照成績概率分布的規(guī)律,如下圖烙荷,更改成績等級判斷邏輯,那么程序判斷的次數(shù)將大大較少檬寂。

更改后的邏輯判斷

二终抽、赫夫曼定義

按照上面的兩種邏輯,可以把上述的邏輯分別簡化成下圖的二叉樹結構。其中A表示不及格昼伴、B及格匾旭、C中等、D良好圃郊、E優(yōu)秀价涝。分支線上的數(shù)字表示成績所占比例數(shù)。

屏幕快照 2017-09-11 下午11.37.15.png
在說赫夫曼之前先說明另個概念:
  • 路徑長度: 從樹中的一個結點到另一個結點之間的分支構成兩個結點之間的路徑,路徑上的分支數(shù)目稱作路徑長度持舆。
  • 樹的路徑長度 : 樹的路徑長度就是從樹根到每一個結點的路徑長度之和飒泻。
說完了上述的兩個概念,看一下赫夫曼樹的定義吏廉。
若將樹中結點賦給一個有著某種含義的數(shù)值泞遗,則這個數(shù)值稱為該結點的權。結點的帶權路徑WPL長度為:從根結點到該結點之間的路徑長度與該結點的權的乘積席覆。給定n個權值作為n的葉子結點史辙,構造一棵二叉樹,若帶權路徑WPL長度達到最小佩伤,稱這樣的二叉樹為最優(yōu)二叉樹聊倔,也稱為哈夫曼樹(Huffman Tree)。

關于赫夫曼樹的定義出現(xiàn)了權生巡。如果考慮到帶權的節(jié)點耙蔑,節(jié)點的帶權路徑長度為從該節(jié)點到樹根之間的路徑長度與節(jié)點上權的乘積。
按照上述所講孤荣,則上圖中二叉樹a的WPL = 5 * 1 + 15 * 2 + 40 * 3 + 30 * 4 + 10 * 4 = 315甸陌。二叉樹b的WPL = 5 * 3 + 15 * 3 + 40 * 2 + 30 * 2 + 10 * 2 = 220。315和220這兩個結果分別意味著盐股,如果用二叉樹 a 的判斷方法钱豁,10000個學生的成績需要做31500次比較,而二叉樹 b 的判斷方法只要做22000次比較疯汁。很顯然牲尺,二叉樹b的效率比a高了很多。

三幌蚊、赫夫曼構造原理

看了上述兩個二叉樹的對比谤碳,但是想二叉樹 b 這樣的高效的二叉樹又是如何得到的?

總共分為四個步驟溢豆。
  • 1蜒简、構成初始集合

對給定的n個權值{W1,W2,W3,...,Wi,...,Wn}構成n棵二叉樹的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉樹Ti中只有一個權值為Wi的根結點沫换,它的左右子樹均為空臭蚁。(為方便在計算機上實現(xiàn)算法,一般還要求以Ti的權值Wi的升序排列讯赏。)

  • 2垮兑、選取左右子樹

在F中選取兩棵根結點權值最小的樹作為新構造的二叉樹的左右子樹,新二叉樹的根結點的權值為其左右子樹的根結點的權值之和漱挎。

  • 3系枪、刪除左右子樹

從F中刪除這兩棵樹,并把這棵新的二叉樹同樣以升序排列加入到集合F中磕谅。

  • 4私爷、重復二和三兩步,

重復二和三兩步膊夹,直到集合F中只有一棵二叉樹為止衬浑。

結合上述的步驟,看看如何將二叉樹 a 轉為二叉樹 b放刨。
  • 第一步,先把有權值得葉子結點按照從小到大的順序排列成一個有序序列,即為A5,D10,B15,C70工秩。

  • 第二步,取頭兩個最小權值的結點作為一個新結點N1的兩個子結點,注意相對較小的的孩子是左孩子,這里A就是N1的左孩子,D為N1的右孩子, 新結點的權值為兩個葉子結點的權值之和 5 + 10 = 15;

第二步
  • 第三步,將N1替換A與E,插入有序序列中,保持從小到大的排序,即 N1 15,B15,C70;

  • 第四步,重復步驟2,將N1與B作為一個新結點N2的兩個子結點, N2的權值 = 15 + 15 = 30;

第四步
  • 第五步,將N2替換N1與B,插入有序序列中,保持從小到大的排序,即 N2 ,D30,C40;

  • 第六步,重復步驟2,將N2和D作為一個新結點N3的兩個子結點进统。N3的權值為30+30 = 60

屏幕快照 2017-09-12 下午10.17.20.png
  • 第七步助币,將N3替換N2和D,排序得到C40螟碎,N3為40眉菱。
  • 第八步,重復步驟二掉分,將C于N3作為一個新節(jié)點T的兩個子節(jié)點俭缓。即完成赫夫曼樹的構造。


    赫夫曼樹構造完成

四酥郭、赫夫曼編碼

赫夫曼樹最大的成績是在當前遠距離通訊過程中尔崔,解決了數(shù)據(jù)傳輸最優(yōu)化問題。比如有ABCDEF六個字母褥民,通過0和1編碼用二進制字符發(fā)送季春。編碼后的數(shù)據(jù)為000001010011100101,解碼的時候可以按照3位一份來解碼消返。是上上载弄,不管是任何文字語言,字母或漢字在某一話題或其他方面出現(xiàn)的頻率是不一樣的撵颊。如漢字中的“的”宇攻、“了”、“你”等等倡勇,都是頻率極高的漢字逞刷。所以因為頻頻的不同,可以按照赫夫曼樹的規(guī)律來規(guī)劃。
假設ABCDEF出現(xiàn)的概率分別為27%夸浅、8%仑最、15%、15%帆喇、30%警医、5%。則形成的赫夫曼樹如下圖坯钦。此外我們可以將左右分支分別改為0和1预皇,然后用0和1來編碼字母。則編碼結果為A=01婉刀、B=1001吟温、C=101、D=00突颊、E=11溯街、F=1000。

按照赫夫曼樹編碼
原本的編碼結果為:000001010011100101
現(xiàn)在的編碼結果為:0110011010011100

現(xiàn)在的編碼結果明顯要比之前的少了一些洋丐,短短是幾個字母編碼后呈昔,少的量不是很大,如果是通篇的文章或更多友绝,那么編碼量將會節(jié)省很多堤尾,這就是文件壓縮的原理。并且隨著字符的增多迁客,按照權重優(yōu)先級編碼郭宝,這種壓縮會進一步提升很多。
既然有編碼掷漱,就必然有解碼粘室。簡單說說解碼,按照赫夫曼樹這種編碼方法卜范,非0即1衔统,且每個字符編碼長短不等很容易混淆。所以若要設計出長短不等的編碼海雪,則必須是任意字符的編碼都不是另一個字符編碼的前綴(這種編碼通常稱為前綴編碼)锦爵。自己觀察A=01、B=1001奥裸、C=101险掀、D=00、E=11湾宙、F=1000根本就不存在容易和 1001 樟氢、1000混淆的10和100編碼冈绊,這一點從上面的0和1的左右分支圖也能輕易的總結出,因為ABCDEF這幾個字符都在輸?shù)淖钅┒瞬嚎校圆粫霈F(xiàn)這種容易混淆的問題死宣。另外一點,當然是編碼和解碼都要規(guī)定好同樣的赫夫曼編碼規(guī)則霸妹。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末十电,一起剝皮案震驚了整個濱河市知押,隨后出現(xiàn)的幾起案子叹螟,更是在濱河造成了極大的恐慌,老刑警劉巖台盯,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罢绽,死亡現(xiàn)場離奇詭異,居然都是意外死亡静盅,警方通過查閱死者的電腦和手機良价,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒿叠,“玉大人明垢,你說我怎么就攤上這事∈醒剩” “怎么了痊银?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長施绎。 經(jīng)常有香客問我溯革,道長,這世上最難降的妖魔是什么谷醉? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任致稀,我火速辦了婚禮,結果婚禮上俱尼,老公的妹妹穿的比我還像新娘抖单。我一直安慰自己,他們只是感情好遇八,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布臭猜。 她就那樣靜靜地躺著,像睡著了一般押蚤。 火紅的嫁衣襯著肌膚如雪蔑歌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天揽碘,我揣著相機與錄音次屠,去河邊找鬼园匹。 笑死,一個胖子當著我的面吹牛劫灶,可吹牛的內容都是我干的裸违。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼本昏,長吁一口氣:“原來是場噩夢啊……” “哼供汛!你這毒婦竟也來了?” 一聲冷哼從身側響起涌穆,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤怔昨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宿稀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趁舀,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年祝沸,在試婚紗的時候發(fā)現(xiàn)自己被綠了矮烹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡罩锐,死狀恐怖奉狈,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情涩惑,我是刑警寧澤仁期,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站境氢,受9級特大地震影響蟀拷,放射性物質發(fā)生泄漏。R本人自食惡果不足惜萍聊,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一问芬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寿桨,春花似錦此衅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至预烙,卻和暖如春墨微,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扁掸。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工翘县, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留最域,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓锈麸,卻偏偏與公主長得像镀脂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子忘伞,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容