數據結構 | 四種平衡二叉樹介紹

2021-02-21 汪汪汪233
歡迎觀看論文系列

二叉樹(Binary Tree)指的是樹中結點的度不大於2的有序樹,其遞歸定義是:二叉樹是一棵空樹,或者是一棵由一個根節點和兩棵互不相交的,分別稱作根的左子樹和右子樹組成的非空樹;左子樹和右子樹同樣也是二叉樹。

二叉樹是樹形結構的一個重要類型,許多實際問題抽象出來的數據結構往往都是二叉樹的類型。即使是一般的樹也可以轉化為二叉樹,並且二叉樹的存儲結構和算法相對而言都比較簡單。因此研究二叉樹對於研究數據結構有著重要的意義。

基於二叉樹在數據結構中的重要作用,本篇文章中將探討二叉樹的一個重要應用,即作為二叉搜索樹時能夠發揮的作用。同時,本文也進一步探討研究了較常使用的平衡二叉樹和六種不同的平衡二叉樹的性能並對其做了對比分析,為未來計算機應用提供了可供參考的意見。

1  二叉搜索樹1.1  二叉搜索樹(BST)

二叉搜索樹(Binary Search Tree)又稱二叉查找樹或二叉排序樹。作為一種經典的數據結構,它既有鍊表的快速插入與刪除操作的特點,又有數組快速查找的優勢。

二叉搜索樹的定義也是遞歸的。它是一棵空樹,或者是滿足下列性質的二叉樹:

每個結點都有一個作為搜索依據的關鍵碼(key),所有節點的關鍵碼互不相同;

左子樹(如果存在)上所有結點的關鍵碼都小於根;

右子樹(如果存在)上所有結點的關鍵碼都大於根;

左子樹和右子樹也是一棵二叉搜索樹。

如下圖所示,就是一棵標準的二叉搜索樹:


1.1.1 搜索

二叉樹的搜索是一個遞歸的過程,流程圖如下所示:


從樹根出發,逐步的縮小查找範圍,直到發現目標(成功)或者縮小至空結點(失敗)。對於該過程而言,在二叉搜索樹的每一層,查找算法至多訪問一個結點,並且只需要常數時間。因此,總體所需時間應當線性正比於查找路徑的長度,或最終返回結點的深度。對於規模為n的二叉搜索樹,深度在最壞情況下可達(n)。

1.1.2 插入

二叉搜索樹的插入的流程圖如下所示:


為了在二叉搜索樹中插入一個結點,首先需要利用其搜索操作查找到插入的位置,然後再將新結點作為葉子結點插入(或者更新已存在結點的值)。由於該操作依賴於搜索操作,因此時間複雜度也為O(n)。

1.1.3 刪除

二叉搜索樹的刪除的流程圖如下所示:


二叉搜索樹的刪除過程也依賴於其查找過程,故時間複雜度也為O(n)。

1.2  平衡二叉搜索樹(BBST)

由於二叉搜索樹在最壞情況下可能退化為列表,此時的各種效率降至O(n)。因此如果不能有效的控制樹高,二叉搜索樹無法體現出明顯的優勢。因此,需要依照某種寬鬆的標準,重新定義二叉搜索樹的平衡性。

平衡二叉搜索樹(Balanced Binary Search Tree)指的是在某種約束條件下,樹高漸進地不超過O(logN)。在這一約束條件下,各種操作的時間複雜度即可降低為O(logN)。它為每一個結點v的平衡因子(balance factor)定義為左、右子樹的高度差,即

balFac(v) = height(lc(v)) - height(rc(v))

下圖即為定義了平衡因子的二叉搜索樹:


通過設定這種約束條件,即可達到搜索樹的最佳性能。後續將介紹六種二叉搜索樹。

2 六種平衡二叉搜索樹2.1 高度平衡樹(AVL)

AVL是最早發明自平衡二叉樹,它被稱作高度平衡樹。在ALV樹中,任意結點平衡因子的絕對值不超過1,即:

|balFac(v)|≤1

2.1.1 平衡性


如上圖所示,不妨設結點數最少的AVL樹S的根結點為r,r的左、右子樹分別為lc和rc,記規模為|lc|和|rc|,高度為h_l和h_r,則有:|S|=1+|lc|+|rc|由於S的子樹lc和rc也是AVL樹,並且高度不超過h-1。因此,不妨取:h_l=h-1, h_r=h-2,|S|=1+| S(h-1) |+| S(h-2) |,由歸納假設,可以獲得如下關係:|S|=1+(fib(h+2)-1)+(fib(h+1)-1)而根據Fibonacci數列的定義,可以獲得:|S|=fib(h+2)+fib(h+1)-1=fib(h+3)-1             因此,可以知道:高度為h的AVL樹至少包含fib(h+3)-1個結點。由於fib(h)和n次方正比,於是包含n個結點的AVL樹的高度應為O(log⁡n )。綜上可知,AVL樹的確是平衡的。

2.1.2 旋轉

AVL樹的插入過程和一般二叉搜索樹的過程相同,即:從樹根出發,逐步的縮小查找範圍,直到發現目標(成功)或者縮小至空結點(失敗)。

不同之處在於,二叉樹在插入或者刪除時,需要維持其平衡。而維持平衡這一過程,正是通過旋轉(Rotate)操作來實現的。AVL樹的旋轉可以歸納為四種:LL單右旋、RR單左旋、LR先左旋再右旋和RL先右旋再左旋。





2.1.3 性能分析

通過2.1.2的旋轉操作,AVL樹可以滿足其性質的定義,通過2.1.1證明可知:包含n個結點的AVL樹的高度應為logn 。

由於二叉搜索樹的查找操作時間正比於樹高,因此AVL樹查找的時間複雜度為O(logN) 。同理,插入和刪除的時間複雜度也為(logN)。

2.2 伸展樹(ST)

伸展樹(Splay Tree)也叫分裂樹,相對於AVL樹實現更為簡捷。伸展樹無需時刻都嚴格地保持全樹的平衡,但卻能夠在任何足夠長的真實操作序列中,保持分攤意義上的高效率。伸展樹也不需要對基本的二叉樹節點結構,做任何附加的要求或改動,更不需要記錄平衡因子或高度之類的額外信息,故適用範圍更廣。

每次查找節點之後對樹進行重構,把被查找的節點搬移到樹根。每次對伸展樹進行操作後,它均會通過伸展(Splay)的方法使得被訪問結點置於根結點的位置。

2.2.1 伸展

與普通的二叉搜索樹的區別在於,伸展樹通過伸展操作將元素調整至根結點的位置。這一調整根據結點所在位置的不同,採用不同的調整方法:

情形旋轉方法單R型左旋轉單L型右旋轉RR型兩次左旋轉LL型兩次右旋轉RL型先右旋轉再左旋轉LR型先左旋轉再右旋轉2.2.2 性能分析

伸展樹能夠在O(log⁡n)內完成插入、查找和刪除操作。它在不保證最壞情況下的時間複雜度是O(log⁡n),其邊界是均攤的。但是,它有一個最顯著的缺點,即有可能變成一條鏈,這種情況下時間複雜度高達O(n)。

2.3 紅黑樹(RBT)

紅黑樹(Red Black Tree)是一種自平衡二叉搜索樹,它等價於4階B-樹。它實際上是一種特化的AVL,均是在進行插入和刪除操作時通過特定操作保持二叉搜索樹的平衡,從而獲得了較高的查找性能。

紅黑樹保持適度平衡的關鍵在於:任一結點左、右子樹的高度,相差不得超過兩倍。為了保持這一平衡,紅黑樹為其內部的每一個結點定義了顏色屬性黑色或者紅色(本文章中紅黑樹黑底表示黑色結點,白底表示紅色結點)。


與上述二叉搜索樹不同,紅黑樹引入了外部結點作為葉結點(圖11中的黑色矩形即為葉結點),它滿足下述性質:

每個結點要麼是黑色,要麼是紅色;

根結點是黑色的;

每個葉結點(NIL)是黑色的;

每個紅色結點的兩個子結點一定都是黑色的;

任意一個結點到每個葉結點的路徑都包含相同數量的黑色結點。

事實上,正是由於性質(5),紅黑樹的這種平衡被稱作黑色完美平衡。紅黑樹維持平衡主要依靠三種方法:左旋、右旋和染色(結點的顏色由黑變紅或者由紅變黑)。

2.3.1 平衡性

2.3.2 三種操作

由於紅黑樹是一棵二叉搜索樹,並且查找並不會破壞樹的平衡,因此查找和二叉搜索樹的查找無異,是一個遞歸的過程。

紅黑樹的插入過程分為兩步,第一步是查找到插入位置,第二步則是插入後的自平衡。因此,其插入過程可分為下述情況(如圖11所示):

紅黑樹為空樹:將插入的結點作為根結點,並且染色為黑色;

插入結點的父結點為黑色結點:直接插入即可;

插入結點的父結點為紅色結點:

若叔叔結點存在並且為紅色結點,則只需將P和S設置為黑色,PP設置為紅色,接下來遞歸的處理PP結點即可;


若叔叔結點不存在或者為黑色結點,插入結點是父結點的左子結點,父結點是祖先結點的左子結點。該種情況需要將P設為黑色,PP設為紅色,同時對PP進行右旋,如下圖所示。其餘情況實際為該種情況的對稱形式,在此不再贅述。


紅黑樹的刪除過程也是先查找到刪除位置,然後通過旋轉和染色來實現再次平衡。

2.4 替罪羊樹(ST)

替罪羊樹(Scapegoat Tree)不同於上述通過旋轉來維持相對平衡的二叉搜索樹,它是基於一種暴力重構的操作來保持相對平衡的。

2.4.1 平衡因子

替罪羊樹中定義了一個平衡因子α的概念,範圍在0.5到1之間。當某個結點的總結點數* α <它某個子樹的總結點數,便會對該結點執行重構操作。對於α的取值,如果α越小,那麼對平衡的要求越高,重構的次數會更多;α越大,樹的平衡程度越低,重構的次數也會隨之減少。一般而言,α取0.7左右比較合適。

2.4.2 平衡性

2.4.3 重構


如上圖所示的替罪羊樹,若平衡因子  ,則結點v已發生失衡。重構過程如下:

將這棵樹壓扁,存入向量中:


2.重新建樹:每次取區間中點作為根結點,遞歸左右兩邊子樹建樹:


通過上述操作,替罪羊樹即完成了其重構操作。並且由2.4.2中結論可知,每次插入後的重構仍然能保證替罪羊樹各種操作的時間複雜度達到  。

3 平衡搜索樹的性能對比

根據上述介紹可以看出,AVL、伸展樹、紅黑樹和替罪羊樹分別採取了不同的方法實現了相對平衡,複雜度如表2所示。在實際使用時,應當根據工作情景選用:

平衡樹時間複雜度應用AVLO(log n)最早的平衡樹伸展樹均攤O(log n)對區間操作紅黑樹O(log n)綜合效率最高替罪羊樹O(log n)實現較易

編輯:汪汪汪

來源:各種csdn文章

相關焦點

  • 數據結構(八)--平衡二叉樹
    該來的總會來,平衡二叉樹果然又來了....出現背景前文已經研究過普通的二叉樹,為什麼要用二叉樹呢?因為二叉樹的結構可以實現二分法查找的效果。你比如前文介紹的滿二叉樹:如下圖所示,如果你想要查找4號元素,你只需要遍歷3次即可。所以在理想情況下,二叉樹可以優化遍歷。
  • 什麼是平衡二叉樹(AVL)
    AVL 樹得名於它的發明者 G. M. Adelson-Velsky 和 Evgenii Landis,他們在1962年的論文《An algorithm for the organization of information》中公開了這一數據結構。
  • 平衡二叉樹專題
    力扣關於平衡二叉樹的題目還是有一些的,並且都非常經典,推薦大家練習。今天給大家精選了 4 道題,如果你徹底搞明白了這幾道題,碰到其他的平衡二叉樹的題目應該不至於沒有思路。當你領會了我的思路之後, 建議再找幾個題目練手,鞏固一下學習成果。110.
  • 平衡二叉樹 AVL樹結構詳解 [Java實現]
    作者NeroJings來源https://blog.csdn.net/zhang6622056/article/details/82698859本文思維導圖簡述先不說平衡二叉樹,我們單開來說,這樣比較方便理解。
  • 五分鐘帶你玩轉平衡二叉樹
    通過上一篇二叉查找樹的文章,相信大家已經掌握了二叉查找樹的相關概念和操作,如果忘了可以通過下方的連結進行學習。帶你玩轉二叉查找樹本文呢,我們將在二叉查找樹的基礎上,繼續學習一種新的樹狀結構-平衡二叉樹。
  • 數據結構+算法(第11篇)玩平衡二叉樹就像蹺蹺板一樣簡單!
    二分查找樹》中提到了:平衡二叉樹的目的就是使得平均查找長度最短。那麼這裡就引出兩個問題:什麼是平衡二叉樹?為什麼平衡二叉樹的平均查找長度最短?如何將非平衡二叉樹調整成平衡二叉樹?1. 平衡二叉樹是什麼鬼?
  • 「算法與數據結構」二叉樹之美
    前言這次梳理的內容是數據結構專題中的「樹」,如果你看到樹這類數據結構時,滿腦子頭疼,覺得它很難理解,如果是這樣子的話,那麼本文可能對你或許有點幫助。俗話說得好,要想掌握理解的話,我們得先了解它的概念,性質等內容。
  • 一文讀懂平衡二叉樹|技術頭條
    作者 | 宋廣澤責編 | 伍杏玲出品 | CSDN(ID:CSDNnews)平衡二叉樹,又稱AVL樹,指的是左子樹上的所有節點的值都比根節點的值小,而右子樹上的所有節點的值都比根節點的值大,且左子樹與右子樹的高度差最大為1。因此,平衡二叉樹滿足所有二叉排序(搜索)樹的性質。
  • 騰訊面試題:有了二叉查找樹、平衡樹為啥還需要紅黑樹?
    本文作者:帥地紅黑樹算是很難的一種數據結構吧,一般很少考察插入、刪除等具體操作步驟,如果遇到要你手寫紅黑樹的面試官,就直接告辭吧。所以,更多是會考察你對紅黑樹的理解程度,考察的最多的估計就是為什麼有了二查找查找樹/平衡樹還需要紅黑樹這個問題了,今天,你只需要花一分鐘的時間,就知道怎麼回答這個問題了。
  • Python 必知數據結構——二叉堆的實現
    我們將會發現,對於下一節要學的圖算法中的優先隊列是很有用的數據結構。我們很自然地會想到用排序算法和隊列的方法來實現優先隊列。但是,在列表裡插入一個元素的時間複雜度是O(n),對列表進行排序的時間複雜度是O(nlogn)。我們可以用別的方法來降低時間複雜度。一個實現優先隊列的經典方法便是採用二叉堆(Binary Heap)。二叉堆能將優先隊列的入隊和出隊複雜度都保持在O(logn)。
  • 【數據結構與算法圖文動畫詳解】終於可以徹底弄懂:紅黑樹、B-樹、B+樹、B*樹、滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜索樹
    紅黑樹和平衡二叉樹區別如下:(1) 紅黑樹放棄了追求完全平衡,追求大致平衡,在與平衡二叉樹的時間複雜度相差不大的情況下,保證每次插入最多只需要三次旋轉就能達到平衡,實現起來也更為簡單。(2) 平衡二叉樹追求絕對平衡,條件比較苛刻,實現起來比較麻煩,每次插入新節點之後需要旋轉的次數不能預知。
  • 數據結構學習筆記:樹與樹的表示、二叉樹及其遍歷、二叉搜索樹、平衡二叉樹、堆、哈夫曼樹、集合及其運算
    2、二叉樹及存儲結構二叉樹的定義二叉樹T:一個有窮的結點集合    這個集合可以為空    若不為空,則它是由根結點和稱為其左子樹TL和右子樹TR的兩個不相交的二叉樹組成特殊二叉樹斜二叉樹(Skewed Binary
  • b樹和b+樹的區別是什麼?b+樹數據結構詳細介紹
    B樹即二叉搜索樹,所有非葉子結點至多擁有兩個兒子(Left和Right,所有結點存儲一個關鍵字,非葉子結點的左指針指向小於其關鍵字的子樹,右指針指向大於其關鍵字的子樹。那麼b+樹和b+樹的區別是什麼?以下是b+樹數據結構詳細介紹。
  • 二叉樹結構相關算法總結 | 原力計劃
    後面如果遇到特殊的思路結構,如多叉樹,我會特別說明。首先我們先給出二叉樹的節點定義(這個定義應該不陌生吧,有刷算法題都會碰到)。以下圖這個簡單的二叉樹遍歷為例:AVL樹AVL 樹是一種平衡二叉樹,平衡二叉樹遞歸定義如下:左右子樹的高度差小於等於 1。其每一個子樹均為平衡二叉樹。
  • 二叉樹的應用—二叉樹遍歷的應用
    下面介紹幾個遍歷操作的典型應用。1.查找數據元素Search(bt,x)在bt 為二叉樹的根結點指針的二叉樹中查找數據元素x。查找成功時返回該結點的指針;查找失敗時返回空指針。算法實現如下,注意遍歷算法中的Visite(bt->data)等同於其中的一組操作步驟。
  • 圖解:數據結構中的各種「樹」,你都心中有數嗎?
    我們在學習數據結構時候,會遇到各種各樣的基礎數據結構,比如堆棧、隊列、數組、鍊表、樹...這些基本的數據結構類型有各自的特點,不同數據結構適用於解決不同場景下的問題。樹是非線性的數據結構,用來模擬具有樹狀結構性質的數據集合,它是由n個有限節點組成的具有層次關係的集合。在數據結構中樹是非線性數據結構,那我們先來了解下,什麼是線性與非線性數據結構?線性結構「線性結構」是一個有序數據元素的集合。
  • 圖解:數據結構中的6種「樹」,你心中有數嗎?
    樹是非線性的數據結構,用來模擬具有樹狀結構性質的數據集合,它是由n個有限節點組成的具有層次關係的集合。在數據結構中樹是非線性數據結構,那我們先來了解下,什麼是線性與非線性數據結構?線性結構「線性結構」是一個有序數據元素的集合。
  • 樹型結構詳解
    本文探討另外一種重要的數據結構----樹,其大部分時間可以保證操作的運行平均時間複雜度為O(logN),第一部分先來看一下樹的一些預備知識。首先看一下樹形結構的樣子,下圖代表的是樹型結構的一般形態:在下一部分的二叉查找樹說明完之後,會講讓二叉樹帶有自平衡條件,成為平衡樹。 二叉查找樹二叉樹的一個重要應用是在它們查找中的使用。
  • 圖解:計算機數據結構中的 6 種「樹」,你心中有數了嗎?
    二叉樹是很多其他樹型結構的基礎結構,比如下面要講的 AVL 樹、二叉查找樹,他們都是由二叉樹增加一些約束條件進化而來。三種遍歷方式二叉樹的遍歷就是逐個訪問二叉樹節點的數據,常見的二叉樹遍歷方式有三種,分別是前中後序遍歷,初學者分不清這幾個順序的差別。
  • 一文徹底弄懂九大常見數據結構!
    線性結構包括常見的鍊表、棧、隊列等,非線性結構包括樹、圖等。數據結構種類繁多,本文將通過圖解的方式對常用的數據結構進行理論上的介紹和講解,以方便大家掌握常用數據結構的基本知識。本文提綱 1  數組數組可以說是最基本最常見的數據結構。數組一般用來存儲相同類型的數據,可通過數組名和下標進行數據的訪問和更新。