BST、B樹、B+樹、紅黑樹之間的總結

1介紹:

1.二叉查找樹,

相信大家都接觸過,二叉查找樹的特點就是左子樹的節點值比父親節點小,而右子樹的節點值比父親節點大,如圖

640?wx_fmt=png


基於二叉查找樹的這種特點,我們在查找某個節點的時候,可以採取類似於二分查找的思想,快速找到某個節點。n 個節點的二叉查找樹,正常的情況下,查找的時間複雜度爲 O(logn)。

之所以說是正常情況下,是因爲二叉查找樹有可能出現一種極端的情況,例如

640?wx_fmt=png


這種情況也是滿足二叉查找樹的條件,然而,此時的二叉查找樹已經近似退化爲一條鏈表,這樣的二叉查找樹的查找時間複雜度頓時變成了 O(n),可想而知,我們必須不能讓這種情況發生,爲了解決這個問題,於是我們引申出了平衡二叉樹

2、平衡二叉樹

平衡二叉樹就是爲了解決二叉查找樹退化成一顆鏈表而誕生了,平衡樹具有如下特點

1、具有二叉查找樹的全部特性。

2、每個節點的左子樹和右子樹的高度差至多等於1。

例如:圖一就是一顆平衡樹了,而圖二則不是(節點右邊標的是這個節點的高度)

640?wx_fmt=png

640?wx_fmt=png


對於圖二,因爲節點9的左孩子高度爲2,而右孩子高度爲0。他們之間的差值超過1了。

於是,通過平衡樹,我們解決了二叉查找樹的缺點。對於有 n 個節點的平衡樹,最壞的查找時間複雜度也爲 O(logn)。

3、紅黑樹

雖然平衡樹解決了二叉查找樹退化爲近似鏈表的缺點,能夠把查找時間控制在 O(logn),不過卻不是最佳的,因爲平衡樹要求每個節點的左子樹和右子樹的高度差至多等於1,這個要求實在是太嚴了,導致每次進行插入/刪除節點的時候,幾乎都會破壞平衡樹的第二個規則,進而我們都需要通過左旋右旋來進行調整,使之再次成爲一顆符合要求的平衡樹。

顯然,如果在那種插入、刪除很頻繁的場景中,平衡樹需要頻繁着進行調整,這會使平衡樹的性能大打折扣,爲了解決這個問題,於是有了紅黑樹,紅黑樹具有如下特點:

1、具有二叉查找樹的特點。

2、根節點是黑色的;

3、每個葉子節點都是黑色的空節點(NIL),也就是說,葉子節點不存數據。

4、任何相鄰的節點都不能同時爲紅色,也就是說,紅色節點是被黑色節點隔開的。

5、每個節點,從該節點到達其可達的葉子節點是所有路徑,都包含相同數目的黑色節點。

例如下面的圖片(注意,圖片中黑色的、空的葉子節點沒有畫出)(圖片來自極客時間)

640?wx_fmt=png

正是由於紅黑樹的這種特點,使得它能夠在最壞情況下,也能在 O(logn) 的時間複雜度查找到某個節點。至於爲什麼就能夠保證時間複雜度爲 O(logn),我這裏就不細講了,後面的文章可能會講。

不過,與平衡樹不同的是,紅黑樹在插入、刪除等操作,不會像平衡樹那樣,頻繁着破壞紅黑樹的規則,所以不需要頻繁着調整,這也是我們爲什麼大多數情況下使用紅黑樹的原因。

不過,如果你要說,單單在查找方面的效率的話,平衡樹比紅黑樹快。

所以,我們也可以說,紅黑樹是一種不大嚴格的平衡樹。也可以說是一個折中發方案。

4.B樹?


B樹是一種平衡多路搜索樹,他的每個節點可以擁大於等於2個子節點,M路的B樹最多能擁有M個子節點,一個節點中有 m 個子節點則存在 m-1 個記錄,記錄按照遞增次序進行排列,葉節點都在同一層上。B樹之所以多路(也就是每個節點上可存多個記錄)是爲了降低高度,路數越多,樹高度越低,查詢性能也高。但也不能是無限的,否則就退化成有序數組了。
 

å¨è¿éæå¥å¾çæè¿°


退化成有序數組的B樹
 

å¨è¿éæå¥å¾çæè¿°
5.B+樹?
B+樹是在B樹基礎上進行改造,他的數據都在葉子結點,同時葉子結點之間還加了指針形成一個鏈表。

å¨è¿éæå¥å¾çæè¿°

Q1.爲什麼不用二叉查找樹作爲數據庫索引?

二叉查找樹,查找到指定數據,效率其實很高logn。但是數據庫索引文件有可能很大,關係型數據存儲了上億條數據,索引文件大則上G,不可能全部放入內存中,
而是需要的時候換入內存,方式是磁盤頁。一般來說樹的一個節點就是一個磁盤頁。如果使用二叉查找樹,那麼每個節點存儲一個元素,查找到指定元素,需要進行大量的磁盤IO,效率很低。
而B樹解決了這個問題,通過單一節點包含多個data,大大降低了樹的高度,大大減少了磁盤IO次數。

 

Q2.B樹和二叉查找樹的性能對比?

B樹包括B+樹的設計思想都是儘可能的降低樹的高度,以此降低磁盤IO的次數,因爲一個索引節點就表示一個磁盤頁,頁的換入換出次數越多,表示磁盤IO次數越多,越低效。
B樹算法減少定位數據所在的節點時所經歷的磁盤IO次數,從而加快存取速度。
假設一個節點可以容納100個值,那麼3層的B樹可以容納100萬個數據。(根節點100值,第二層可以存儲99個節點(k-1),也就是99*100 個值,第三層可以存儲
(99*100-1)*100)結果是近似100萬個數據。而如果使用二叉查找樹,則需要將近20層,也就是進行20次磁盤IO,性能差距如此之大。
如mongoDB數據庫使用,單次查詢平均快於Mysql(但側面來看Mysql至少平均查詢耗時差不多)。

 

Q3.B+對比B樹的優點?

因爲B樹的每個節點除了存儲指向子節點的索引之外,還有data域,因此單一節點存儲的指向子節點的索引並不是很多,樹高度較高,磁盤IO次數較多,
而B+樹單一節點存儲的指向子節點的索引更多,B+樹空間利用率高,因此B+樹高度更低,磁盤IO次數更少,性能更好。
因爲B樹的中間節點存儲了數據,所以整個樹的每一層都有可能查找到要查找的數據,查詢性能不穩定,
而B+樹所有的data都存儲在葉子節點,且葉子節點位於同一層,因此查詢性能穩定。
B樹如果想要進行範圍查找,需要頻繁的進行二叉樹的中序遍歷,進行範圍查找比較複雜,
B+樹要查找的元素都位於葉子節點,且連接形成有序鏈表,便於範圍查找。

 

Q4.B樹,B+樹使用場景。

B樹主要用於文件系統,和部分數據庫索引,如文檔型數據庫mongodb
B+樹主要用於mysql數據庫索引。

 

Q5.爲什麼數據庫索引不用紅黑樹而用B+樹?

紅黑樹當插入刪除元素的時候會進行頻繁的變色與旋轉(左旋,右旋),來保證紅黑樹的性質,浪費時間。
但是當數據量較小,數據完全可以放入內存中,不需要進行磁盤IO,這時候,紅黑樹時間複雜度比B+樹低。
比如TreeSet TreeMap 和HashMap (jdk1.8)就是使用紅黑樹作爲底層數據結構。



6:爲什麼用B+樹存儲索引而不用B樹?


這也是和業務場景相關的,一般去數據庫查詢數據,不一定只選一條,很多時候會選多條數據,在查多條情況下,B樹需要做局部的中序遍歷,可能要跨層訪問。而B+樹由於所有數據都在葉子結點,不用跨層,同時由於有鏈表結構,只需要找到首尾,通過鏈表就能把所有數據取出來了。

7:爲什麼用B+樹做索引?


我們在MySQL中的數據一般是放在磁盤中的,讀取數據的時候肯定會有訪問磁盤的操作,磁盤中有兩個機械運動的部分,分別是盤片旋轉和磁臂移動。盤片旋轉就是我們市面上所提到的多少轉每分鐘,而磁臂移動則是在盤片旋轉到指定位置以後,移動磁臂後開始進行數據的讀寫。那麼這就存在一個定位到磁盤中的塊的過程,而定位是磁盤的存取中花費時間比較大的一塊,畢竟機械運動花費的時候要遠遠大於電子運動的時間。當大規模數據存儲到磁盤中的時候,顯然定位是一個非常花費時間的過程,但是我們可以通過B樹進行優化,提高磁盤讀取時定位的效率。

爲什麼B類樹可以進行優化呢?我們可以根據B類樹的特點,構造一個多階的B類樹,然後在儘量多的在結點上存儲相關的信息,保證層數儘量的少,以便後面我們可以更快的找到信息,磁盤的I/O操作也少一些,而且B類樹是平衡樹,每個結點到葉子結點的高度都是相同,這也保證了每個查詢是穩定的。

一般去數據庫查詢數據,不一定只選一條,很多時候會選多條數據,在查多條情況下,B樹需要做局部的中序遍歷,可能要跨層訪問。而B+樹由於所有數據都在葉子結點,不用跨層,同時由於有鏈表結構,只需要找到首尾,通過鏈表就能把所有數據取出來了。

8:爲什麼用B+樹不用紅黑樹?


總的來說,B/B+樹是爲了磁盤或其它存儲設備而設計的一種平衡多路查找樹(相對於二叉,B樹每個內節點有多個分支),與紅黑樹相比,在相同數據情況下,一顆B/B+樹的高度遠遠小於紅黑樹的高度,這樣在磁盤查找數據時,磁臂定位次數也就越少,查詢效率越高。B/B+樹上操作的時間通常由存取磁盤的時間和CPU計算時間這兩部分構成,而CPU的速度非常快,所以B樹的操作效率取決於訪問磁盤的次數,關鍵字總數相同的情況下B樹的高度越小,磁盤I/O所花的時間越少。

9:既然hash比B+樹快,爲什麼MySQL數據庫要用B+樹存儲索引?


如果只選一個數據,那確實是hash更快。但是數據庫中經常會選擇多條,這時候由於B+樹索引有序,並且又有鏈表相連,它的查詢效率比hash就快很多了。
而且數據庫中的索引一般是在磁盤上,數據量大的情況可能無法一次裝入內存,B+樹的設計可以允許數據分批加載,同時樹的高度較低,提高查找效率。

參考
https://blog.csdn.net/qq_36183935/article/details/81095212
https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw
https://mp.weixin.qq.com/s/jRZMMONW3QP43dsDKIV9VQ
https://blog.csdn.net/zhangshk_/article/details/83013482

https://blog.csdn.net/qq_36533951/article/details/84991777

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章