【数据结构-树】4.图解平衡二叉树和哈夫曼编码(逐步演绎,一文读懂)
一、平衡二叉樹
1.1 什么是平衡二叉樹?
規(guī)定在插入和刪除二叉樹結(jié)點(diǎn)時(shí),要保證任意結(jié)點(diǎn)的左、右子樹高度之差的絕對(duì)值不可以超過1
平衡因子:結(jié)點(diǎn)左子樹和右子樹的結(jié)點(diǎn)高度差為該結(jié)點(diǎn)的平衡因子,也就是說平衡樹的平衡因子只可能是-1,0,1
如下圖,結(jié)點(diǎn)53左子樹高度為3,右子樹高度為2,所以結(jié)點(diǎn)53的平衡因子為1
1.2 為什么需要平很二叉樹?
為了避免樹的高度增長過快,降低二叉樹的性能
如下圖,左邊的圖的最壞查找情況為O(n),而右邊圖的最壞查找情況為O(logn)
1.3 平衡二叉樹的機(jī)制?
總綱:調(diào)整過程應(yīng)該是自下而上的
無論是插入還是刪除,改變一個(gè)結(jié)點(diǎn)的位置就會(huì)導(dǎo)致一棵二叉樹的平衡因子改變。因此,在每插入或者刪除一個(gè)結(jié)點(diǎn)之后,需要重新計(jì)算二叉樹各個(gè)結(jié)點(diǎn)的平衡因子。若右結(jié)點(diǎn)的平衡因子大于1,那么需要調(diào)整這棵二叉樹為平衡二叉樹。當(dāng)該樹再次稱為平衡二叉樹之后,再進(jìn)行下一步的插入或刪除操作。
1. LL型
口訣:左失衡,中為支,高右旋
解釋:如果對(duì)于LL型二叉樹轉(zhuǎn)為平衡二叉樹不是很了解,背口訣套就是了。但是,終究要了解為什么這么做。在這一步的過程中,其實(shí)不需要死記硬背,只需要記住每一步的調(diào)整滿足二叉排序的性質(zhì)和定義,然后從整棵二叉樹分析,在{20,23,45},平衡因子在結(jié)點(diǎn)45時(shí)絕對(duì)值大于1,這么調(diào)整{20,23,45}為一棵平衡二叉樹。顯然,讓中間結(jié)點(diǎn)23(23大于20且小于45)作為根,結(jié)點(diǎn)20和結(jié)點(diǎn)45分別作為結(jié)點(diǎn)23的左右孩子結(jié)點(diǎn),符合調(diào)整意圖
調(diào)整過程如下圖所示
2. RR型
口訣:右失衡,中為支,高左旋
解釋:同樣的道理。從整棵二叉樹分析,在{65,70,75},平衡因子在結(jié)點(diǎn)65時(shí)絕對(duì)值大于1,這么調(diào)整{65,70,75}為一棵平衡二叉樹。顯然,讓中間結(jié)點(diǎn)70(70大于65且小于75)作為根,結(jié)點(diǎn)65和結(jié)點(diǎn)75分別作為結(jié)點(diǎn)70的左右孩子結(jié)點(diǎn),符合調(diào)整意圖
調(diào)整過程如下圖所示
3. LR型
口訣:下二整體左旋,后與LL型調(diào)整一樣
解釋:下二整體左旋的目的就是在局部形成類似LL型失衡情況一樣。在這一步的過程中(下二整體左旋),同樣不需要死記硬背,只要滿足一棵二叉排序樹就可以。比如下圖的操作,將結(jié)點(diǎn)25作為結(jié)點(diǎn)23的雙親結(jié)點(diǎn),同時(shí),23比25小,所以結(jié)點(diǎn)23是結(jié)點(diǎn)25的左孩子結(jié)點(diǎn)。此時(shí),整棵樹就是LL型的二叉樹
調(diào)整過程如下圖所示
4. RL型
口訣:下二整體右旋,后與RR型調(diào)整一樣
解釋:下二整體右旋的目的就是在局部形成類似RR型失衡情況一樣。在這一步的過程中,將結(jié)點(diǎn)68作為結(jié)點(diǎn)70的雙親結(jié)點(diǎn),同時(shí),70比68大,所以結(jié)點(diǎn)70是結(jié)點(diǎn)68的右孩子結(jié)點(diǎn)。此時(shí),整棵樹就是RR型的二叉樹,做RR調(diào)整就可以了
調(diào)整過程如下圖所示
二、哈夫曼樹
1.1 什么是哈夫曼樹?
給定N個(gè)權(quán)值作為N個(gè)葉子結(jié)點(diǎn),構(gòu)造一棵二叉樹,若該樹的帶權(quán)路徑長度達(dá)到最小,稱這樣的二叉樹為最優(yōu)二叉樹,也稱為哈夫曼樹
在深入了解哈夫曼樹之前,我們需要先知道一些必要的基本概念。
如下圖:
圖a:WPL=7?2+5?2+2?2+4?2=36WPL=7*2+5*2+2*2+4*2 = 36WPL=7?2+5?2+2?2+4?2=36
圖b:WPL=7?3+5?3+2?1+4?2=46WPL=7*3+5*3+2*1+4*2 = 46WPL=7?3+5?3+2?1+4?2=46
圖c:WPL=7?1+5?2+2?3+4?3=35WPL=7*1+5*2+2*3+4*3 = 35WPL=7?1+5?2+2?3+4?3=35
比較得知:圖c中樹的WPL最小,所以圖3為一棵哈夫曼樹
1.2 為什么使用哈夫曼樹?
在計(jì)算機(jī)數(shù)據(jù)處理中,哈夫曼編碼使用變長編碼表對(duì)源符號(hào)進(jìn)行編碼,其中變長編碼表是通過一種評(píng)估來源符號(hào)出現(xiàn)機(jī)率的方法得到的,出現(xiàn)機(jī)率高的字母使用較短的編碼,反之出現(xiàn)機(jī)率低的則使用較長的編碼,這便使編碼之后的字符串的平均長度、期望值降低,從而達(dá)到無損壓縮數(shù)據(jù)的目的。
簡單的來說,就按出現(xiàn)的頻率不同,把高頻率出現(xiàn)的目標(biāo)放在距離根結(jié)點(diǎn)近的位置,低頻率出現(xiàn)的目標(biāo)放在距離根結(jié)點(diǎn)源的位置,這樣就使得查找效率提高。
1.3 如何使用哈夫曼樹?
給定n個(gè)權(quán)值分別為 w1,w2,…,wnw_1,w_2,…,w_nw1?,w2?,…,wn? 的結(jié)點(diǎn),通過哈夫曼算法可以構(gòu)造出最優(yōu)二叉樹。
哈夫曼樹有如下特點(diǎn):
哈夫曼樹的構(gòu)造過程
最后穩(wěn)一點(diǎn),大家認(rèn)為哈夫曼樹是唯一的嘛?顯然不是。因?yàn)槎鏄涫欠肿笥医Y(jié)點(diǎn)的,比如上圖(c)中,結(jié)點(diǎn)c是雙親結(jié)點(diǎn)的左孩子結(jié)點(diǎn),結(jié)點(diǎn)d是雙親結(jié)點(diǎn)的右孩子結(jié)點(diǎn),二者交換位置也是可以的,并不影響整棵樹是一棵哈夫曼樹(WPL沒有改變)。所以哈夫曼樹答案不唯一。
1.4 哈夫曼編碼
為使不等長編碼為前綴編碼(即要求一個(gè)字符的編碼不能是另一個(gè)字符編碼的前綴),可用字符集中的每個(gè)字符作為葉子結(jié)點(diǎn)生成一棵編碼二叉樹,為了獲得傳送報(bào)文的最短長度,可將每個(gè)字符的出現(xiàn)頻率作為字符結(jié)點(diǎn)的權(quán)值賦予該結(jié)點(diǎn)上,顯然字使用頻率越小權(quán)值越小,權(quán)值越小葉子就越靠下,于是頻率小編碼長,頻率高編碼短,這樣就保證了此樹的最小帶權(quán)路徑長度效果上就是傳送報(bào)文的最短長度。
因此,求傳送報(bào)文的最短長度問題轉(zhuǎn)化為求由字符集中的所有字符作為葉子結(jié)點(diǎn),由字符出現(xiàn)頻率作為其權(quán)值所產(chǎn)生的哈夫曼樹的問題。利用哈夫曼樹來設(shè)計(jì)二進(jìn)制的前綴編碼,既滿足前綴編碼的條件,又保證報(bào)文編碼總長最短。
若沒有一個(gè)編碼是另一個(gè)編碼的前綴,則稱這樣的編碼為前綴編碼。
通過前綴編碼解碼,可以辨識(shí)出第一個(gè)編碼,并將編碼翻譯為源原碼。
例如:00101100,可以唯一被解讀為:0、0、101、100
下面舉個(gè)例子
a:01
b:10
c:110
d:111
e:00
通過上面的例子可以看出,對(duì)于每個(gè)葉子結(jié)點(diǎn)上的值都有唯一的編碼
總結(jié)
以上是生活随笔為你收集整理的【数据结构-树】4.图解平衡二叉树和哈夫曼编码(逐步演绎,一文读懂)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构-树】3.详解二叉排序树(理论
- 下一篇: 【数据结构-栈和队列】详解栈和队列(代码