AVL樹、B-樹、RB樹、B+樹、B*樹比較
一:AVL樹
也就是平衡二叉樹,該二叉樹為了優化查詢的效能,會讓每個結點的左右子樹的高度差維持在1以內,也就是小於等於1。因為我們在二叉查詢樹上查詢資料的時候,是類似二分法的,那麼我們每次折半的區間長度就會決定了我們查詢的效率,從概率的角度講,在未知的情況下肯定是一半一半獲得的效率最高。所以在二叉查詢樹中,決定查詢效率就是樹的高度,為什麼呢?
其實我們可以這樣想,因為我們每次在二叉樹中查詢的時候,沒經過一層,總是選擇的其中一個結點進行的比較,也就意味著另外一個結點是我們跨越的步長,前面我們說到過一半一半的效率肯定是最高的,那麼維持這樣的形式產生的結果就是AVL樹,因為在儘可能的維持每步跨越結點一樣的時候,二叉查詢樹就比較自然的演變成了AVL樹,因為在左右子樹高度差小於等於1的情況下,結點會盡可能的填滿每一個父結點,而不會出現二叉查詢樹的一邊偏向的問題。
綜上所述,AVL樹是一種二叉查詢樹的優化結構,旨在提高查詢的效率。但是帶來的問題是需要在插入結點和刪除結點的時候維持整棵樹的平衡性,在有的情況下,這可能得不償失,也就是意味著,我們維護二叉查詢樹的平衡性的代價大於最後我們查詢所獲得的額外的收益。
二:B-樹
前面我們陳述了一個問題,那就是樹的結點的高度差會影響結點的查詢效率,那麼下面我們再來分析一個相關的因素,那就是整棵樹的高度。我們可以這樣來想因為二叉查詢樹在每個結點都存放了資料,那麼在最好的情況下查詢到資料就是在根節點的情況下,但是這種情況在大量的查詢下發生的概率是極低的,反而大部分的情況我們都會查詢到葉子結點,為什麼呢?
其實如果是在大量操作的情況下,那麼從概率的角度出發就是很有說服力的,我們可以看到越接近葉子結點每層的結點數就越多,我們先假設查詢的資料是隨機並且等概率的(當然只是一個粗略的估計),那麼結點數越多的層數始終會出現一種統計上的優勢,即大概率發生,甚至必定發生,顯然葉子結點層是擁有最多的結點的層,並且越靠近葉子結點的層數的結點數就越多,那麼我們有理由認為查詢的結果大概率會發生在葉子結點或者靠近葉子結點的地方。所以整棵樹的高度就顯得尤為重要了,為什麼呢?因為我們在查詢的時候樹的高度代表我們要檢索的次數,顯然好似樹越低我們查詢到就越快。
而且B-樹的資料如果是儲存在外存的,那麼磁碟的IO次數將是效率的決定行因素,所以樹的高度越低代表需要I/O的次數越少。
綜上所述:B-樹是一棵多叉平衡搜尋樹,旨在比AVL樹能夠擁有更低的樹高,提高查詢的效率,但是同AVL樹一樣,面對插入和刪除資料的操作後需要維持平衡,這可能帶來一些得不償失的情況。其次B-樹可以被採用在外存的資料查詢上,因為樹高比較低,這樣就可以減少磁碟的I/O次數。
三:RB樹(紅黑樹):
相當於是一個3叉的搜尋樹,因為在一些相當多的情況下,我們可以只用三叉就不會產生很高的樹,那麼我們就決定採用3叉樹,但是前面我們提到了一個問題,那就是插入和刪除資料的時候,會帶來繁瑣的調整整棵樹平衡性的操作。所以在一些情況下,我們做出了時間和效率的權衡,我們採用一種3叉B-樹的變體,也就是紅黑樹。
紅黑樹的優點是,不是絕對的平衡,但是又加入了限制的條件,可以讓結點間的樹高差距限定在一定的範圍內(最高高度結點的高度不高於最低高度結點高度的兩倍)。並且採取了將B-樹用二叉樹的形式表現出來,大大簡化了插入和刪除的操作。
綜上所述:紅黑樹其實就是3叉B-樹,只是進行了一個優化,使其查詢,插入,刪除的總體效果得到優化。
四:B+樹:
應用於資料庫等將資料存放在外存的情況下,這種結構是對B-樹進行的一個變化,使其更加的適合在磁碟上資料的插入、刪除、查詢等。因為我們前面說過當資料存放在外存的時候,限制查詢等操作的就不再是記憶體中的有限操作了,而是磁碟的I/O,因為磁碟的速度是完全不可能與CPU和記憶體打交道的速度相提並論的。所以我們有一個最大的需求,那就是減少I/O次數,基於此我們採用了多叉的情況(比B-樹更多叉),這就使得樹可以更矮,其次我們B+樹的資料全部儲存在葉子結點,中間的結點只是儲存鍵值,不儲存資料,那麼也就是在相同的磁碟塊的大小的情況下,我們可以儲存更多的索引,這樣也可以減少磁碟的I/O次數。然後我們在樹的葉子結點間進行了一個連結的操作,這是便於我們進行範圍查詢,因為在B-樹中進行範圍查詢將是十分困難的,需要採用中序遍歷,非常繁瑣,基於這個考量增加了葉子結點間的指標(因為資料庫中範圍查詢是應用得相當多。)
五:B*樹:
B+樹的變體,增加了空間利用率的下限。