语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树
引言
《菜鳥也能“種”好二叉樹!》一文中提到了:為了方便查找,需要進行分層分類整理。而滿足這種目標的數據結構之一就是樹。
樹的葉子節點可以看作是最終要搜尋的目標物;葉子節點以上的每一層,都可以看作是一個大類別、層中的每個節點都可以看作是一個小類別。
從上圖可以看出,要定位目標物,就需要從最上面的大類依次向下定位目標物所屬的小類。
定位的效率(時間復雜度)取決于兩個因素:
研究問題都講究由簡到繁,那就讓我們先來看看最簡單的情形——分岔數最小的情形——二叉樹。
二叉樹的每層節點只有兩個節點,這表示只有兩個小類。定位屬于哪個小類時,需要做比較。比較的次數越少、比較的方法越簡單,效率也就越高。
比較次數再怎么少也得1次、最簡單的比較方法就是比大小。為了滿足這個目標,前輩們就對一般二叉樹加了如下規則:
每個非葉子節點的左孩子的值不大于該節點本身的值;右孩子的值不小于該節點本身的值。
這樣的二叉樹就稱為“二分查找樹”。
二分查找樹的數學思想
將二分查找樹從根節點(最大類)到葉子節點(目標物)的路徑扒出來,垂直放置之后就如下圖左部所示。再“倒”下來水平放置之后,就如下圖右部所示。
由此可以看出,從最大類到目標物的查找過程,其實就是從大類不斷逼近目標物的過程。
這個思想的本質其實就是數學的“逼近法”——不斷縮小范圍、直至不可再小,最終剩下的即為所求。
“逼近法”思想大量在數學中應用。牛頓當年發明微積分,其證明過程其實采用的也是“逼近法”。具體可以參見牛頓的曠世巨著《自然哲學的數學原理》第一編《物體的運動》的第1章《初量與終量的比值方法》的引理2。
牛頓
《自然哲學的數學原理》
二分查找法
基于二分查找樹數據結構的搜索算法稱為“二分查找法”。
二分查找樹是一個遞歸定義,所以很容易得出遞歸版的二分查找法。
下面以鏈表形式存儲的二分查找樹為例,數組形式存儲的,可以根據父子節點下標的線性關系(《菜鳥也能“種”好二叉樹!》一文中的推論5.2.1),類似推導,在此就不贅述了。
還是根據《史上最猛之遞歸屠龍奧義》一文中的老套路,轉換成非遞歸版本:
整個算法的時間開銷主要由do-while循環體的循環次數決定。很顯然,在最壞情況下,循環次數等于二叉查找樹的高度。假設樹的節點總數為N,則根據《菜鳥也能“種”好二叉樹!》一文中的結論,高度等于logN,從而時間復雜度等于O(logN)。
二分查找樹的節點插入算法
向二分查找樹插入新節點很簡單,從根節點開始,根據定義逐層比較、進入對應子樹下沉、直至葉子節點:
對應的遞歸版算法代碼如下:
還是根據《史上最猛之遞歸屠龍奧義》一文中的老套路,轉換成非遞歸版本:
可以看出,整個算法結構與二分查找樹的搜索算法類似,時間復雜度也是O(logN)。
二分查找樹的節點刪除算法
直接刪除節點,會破壞二叉樹的結構,需要進行調整。
首先需要有節點補上被刪節點的空缺。這個“補漏”有兩個策略:
稍微想一想,就會知道第一種策略比較復雜,因為你需要在一開始就通盤考慮,復雜度很高;
第二種策略其實是一種局部性原理思想——先局部求解、再逐步遞進到全局解。這種局部性原理思想在整個計算機科學中大量使用:比如虛擬內存管理、人工智能的爬山算法等等。
第二種策略其實我們在上一篇《二叉堆“功夫熊貓”的速成之路》中的“Top N”章節中也提到了。有興趣的朋友也可以翻回去看看。
具體實操上,和“Top N”的方法一樣,我們用尾節點“補漏”被刪節點。
上面三張圖形象描繪了整個替換、下推調整的過程。
這里啰嗦一句:因為要先得到尾節點的位置,然后再回到待刪節點位置——這涉及到遍歷和回溯,若采用鏈表存儲整個二叉查找樹的話,就不是很方便。所以針對節點刪除場景,用數組更簡單。
但為了“炫技”,筆者在這里就挑最復雜的單向鏈表式、非遞歸版算法來實現一下:)
最壞情況無外乎刪除根節點——這種情況下下推的距離最長——極限情況下,要下推整個二分查找樹的高度。所以這個算法的時間復雜度不超過O(logN)。
至于數組式、遞歸版算法,讀者可以根據《史上最猛之遞歸屠龍奧義》和《二叉堆“功夫熊貓”的速成之路》中講到的套路,自行推導。
做一棵“穩重的”二分查找樹
上面兩棵二分查找樹是等價的,但是可以很明顯看出:第一棵一些分支會向一邊傾斜,而第二棵就顯得“穩重”多了。
試想,你要搜索值為17的節點。按照前面二分查找樹的搜索算法,對于第一棵樹,從根節點開始,一共需要進行4次比較才能找到;而對于第二棵樹,只需要進行1次比較就能找到!
為什么會有這么大的差別呢?
答案在于:第二棵樹是一棵“平衡二叉樹”,它的“穩重”特點實現了一個目標——平均查找長度最短。
下一篇文章我們就來“盤盤”平衡二叉樹。
若喜歡本篇文章,麻煩打賞、點贊、轉發、收藏、點擊文末廣告!
支持越猛、原創越猛!
《算法素顏》系列連載往期回顧:
《走下神壇吧!算法》
《掃雷還可以這樣玩》
《KO!大O——時間復雜度》
《空間復雜度你真的懂了嗎?》
《小白也能玩轉數組和鏈表啦!》
《再不會"降維打擊"你就Out了!》
《神力加身!動態編程》
《史上最猛之遞歸屠龍奧義》
《菜鳥也能“種”好二叉樹!》
《二叉堆“功夫熊貓”的速成之路》
總結
以上是生活随笔為你收集整理的语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英语语法---短语总结
- 下一篇: 英语语法---从句总结