出處:https://www.jianshu.com/p/86a1fd2d7406
寫在前面,好像不同的教材對b樹,b-樹的定義不一樣。我就不糾結這個到底是叫b-樹還是b-樹了。
如圖所示,區別有以下兩點:
- B+樹中只有葉子節點會帶有指向記錄的指針,而B樹則所有節點都帶有,在內部節點出現的索引項不會再出現在葉子節點中。
- B+樹中所有葉子節點都是通過指針連接在一起,而B樹不會。
B+樹的優點:
- 非葉子節點不會帶上指向記錄的指針,這樣,一個塊中可以容納更多的索引項,一是可以降低樹的高度。二是一個內部節點可以定位更多的葉子節點。
- 葉子節點之間通過指針來連接,范圍掃描將十分簡單,而對於B樹來說,則需要在葉子節點和內部節點不停的往返移動。具體的來講,如何想掃描一次所有數據,對於b+樹來說,可以從因為他們的葉子結點是連在一起的,所以可以橫向的遍歷過去。而對於b-樹來說,就這能中序遍歷了。
B樹的優點:
對於在內部節點的數據,可直接得到,不必根據葉子節點來定位。
B樹長什么樣子?

紅黑樹和B樹應用場景有何不同?
為什么要設計紅黑樹?
先說一下紅黑樹,紅黑樹有一個比較復雜的規則,紅的結點balala怎么樣,黑的結點balalal怎么樣。大一大二學這些的時候,傻呵呵的想背課文一樣背下來,當也不知道為什么要設計成這樣。換一句話說,為什么平衡樹和紅黑樹的區別是什么?為什么有了平衡樹還要設計出來紅黑樹?
紅黑樹的規則:
1)每個結點要么是紅的,要么是黑的。
2)根結點是黑的。
3)每個葉結點(葉結點即指樹尾端NIL指針或NULL結點)是黑的。
4)如果一個結點是紅的,那么它的倆個兒子都是黑的。
5)對於任一結點而言,其到葉結點樹尾端NIL指針的每一條路徑都包含相同數目的黑結點。
現在想想,我的理解是平衡樹(AVL)更平衡,結構上更加直觀,時間效能針對讀取而言更高,但是維護起來比較麻煩!!!(插入和刪除之后,都需要rebalance)。但是,紅黑樹通過它規則的設定,確保了插入和刪除的最壞的時間復雜度是O(log N) 。
設計紅黑樹的目的,就是解決平衡樹的維護起來比較麻煩的問題,紅黑樹,讀取略遜於AVL,維護強於AVL,每次插入和刪除的平均旋轉次數應該是遠小於平衡樹。
小結一下:
能用平衡樹的地方,就可以用紅黑樹。用紅黑樹之后,讀取略遜於AVL,維護強於AVL。
紅黑樹 和 b+樹的用途有什么區別?
-
紅黑樹多用在內部排序,即全放在內存中的,STL的map和set的內部實現就是紅黑樹。
-
B+樹多用於外存上時,B+也被成為一個磁盤友好的數據結構。
為什么b+磁盤友好?
-
磁盤讀寫代價更低
樹的非葉子結點里面沒有數據,這樣索引比較小,可以放在一個blcok(或者盡可能少的blcok)里面。避免了樹形結構不斷的向下查找,然后磁盤不停的尋道,讀數據。這樣的設計,可以降低io的次數。 -
查詢效率更加穩定
非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。 -
遍歷所有的數據更方便
B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而其他的樹形結構 要中序遍歷才可以訪問所有的數據。
題外話:為什么mysql索引使用b+樹而不使用紅黑樹?
b+樹就是為文件存儲而生的。如果數據庫文件存儲在主存中我認為兩種結構的查詢速度差距不是很大,因為主存的查找速度非常快。而數據庫文件實際存儲在磁盤中,定位一行信息需要查找該行文件所在柱面號,磁盤號,扇區號,頁號這個階段是很耗費時間的。每一次的定位請求意味着要做一次IO操作,也意味着成倍的時間消耗。因此減少IO查詢的次數是提高查詢性能的關鍵。而IO的查詢次數就是索引樹的高度,高度越低查詢的次數越少。同樣的結點次數紅黑樹的高度最多為2log(n+1),而B+樹的高度最多為(logt (n+1)/2)+1,隨着t增大高度會更小,IO次數也會減少。