日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树

發布時間:2025/3/12 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 语言非递归求解树的高度_算法素颜(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):无死角“盘”它!二分查找树的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。