1. 程式人生 > >二叉樹,平衡二叉樹,紅黑樹,B-樹、B+樹、B*樹的區別

二叉樹,平衡二叉樹,紅黑樹,B-樹、B+樹、B*樹的區別

二叉查詢/搜尋/排序樹  BST  (binary search/sort tree)
或者是一棵空樹;
或者是具有下列性質的二叉樹:
(1)若它的左子樹不空,則左子樹上所有結點的值均小於它的根節點的值;
(2)若它的右子樹上所有結點的值均大於它的根節點的值;
(3)它的左、右子樹也分別為二叉排序樹。

注意:對二叉查詢樹進行中序遍歷,得到有序集合。

平衡二叉樹(Self-balancing binary search tree)  自平衡二叉查詢樹  又被稱為AVL樹(有別於AVL演算法)
它是一 棵空樹
或它的左右兩個子樹的高度差(平衡因子)的絕對值不超過1,
並且左右兩個子樹都是一棵平衡二叉樹,
同時,平衡二叉樹必定是二叉搜尋樹,反之則不一定

 平衡因子(平衡度):結點的平衡因子是結點的左子樹的高度減去右子樹的高度。(或反之定義)
 平衡二叉樹:每個結點的平衡因子都為 1、-1、0 的二叉排序樹。或者說每個結點的左右子樹的高度最多差1的二叉排序樹。

平衡二叉樹的目的是為了減少二叉查詢樹層次,提高查詢速度

平衡二叉樹的常用實現方法有AVL、紅黑樹、替罪羊樹、Treap、伸展樹等

紅黑樹
    R-B Tree,全稱是Red-Black Tree,又稱為“紅黑樹”,它一種平衡二叉樹。紅黑樹的每個節點上都有儲存位表示節點的顏色,可以是紅(Red)或黑(Black)。

紅黑樹的特性:
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點(NIL)是黑色。 [注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
(4)如果一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

注意:
(01) 特性(3)中的葉子節點,是隻為空(NIL或null)的節點。
(02) 特性(5),確保沒有一條路徑會比其他路徑長出倆倍。因而,紅黑樹是相對是接近平衡的二叉樹

紅黑樹的應用比較廣泛,主要是用它來儲存有序的資料,它的時間複雜度是O(logN),效率非常之高。
    它雖然是複雜的,但它的最壞情況執行時間也是非常良好的,並且在實踐中是高效的: 它可以在O(log n)時間內做查詢,插入和刪除,這裡的n 是樹中元素的數目。
    例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虛擬記憶體的管理,都是通過紅黑樹去實現的。

B-樹
B-樹是一種多路搜尋樹(並不一定是二叉的)
1970年,R.Bayer和E.mccreight提出了一種適用於外查詢的樹,它是一種平衡的多叉樹,稱為B樹(或B-樹、B_樹)。

一棵m階B樹(balanced tree of order m)是一棵平衡的m路搜尋樹。它或者是空樹,或者是滿足下列性質的樹:
1、根結點至少有兩個子女;

2、每個非根節點所包含的關鍵字個數 j 滿足:┌m/2┐ - 1 <= j <= m - 1;

3、除根結點以外的所有結點(不包括葉子結點)的度數正好是關鍵字總數加1,故內部子樹個數 k 滿足:┌m/2┐ <= k <= m ;

4、所有的葉子結點都位於同一層。

特點:
是一種多路搜尋樹(並不是二叉的):

1.定義任意非葉子結點最多隻有M個兒子;且M>2;

2.根結點的兒子數為[2, M];

3.除根結點以外的非葉子結點的兒子數為[M/2, M];

4.每個結點存放至少M/2-1(取上整)和至多M-1個關鍵字;(至少2個關鍵字)

5.非葉子結點的關鍵字個數=指向兒子的指標個數-1;

6.非葉子結點的關鍵字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7.非葉子結點的指標:P[1], P[2], …, P[M];其中P[1]指向關鍵字小於K[1]的

子樹,P[M]指向關鍵字大於K[M-1]的子樹,其它P[i]指向關鍵字屬於(K[i-1], K[i])的子樹;

8.所有葉子結點位於同一層;

如:(M=3)

這裡寫圖片描述

B-樹的搜尋,從根結點開始,對結點內的關鍵字(有序)序列進行二分查詢,如果

命中則結束,否則進入查詢關鍵字所屬範圍的兒子結點;重複,直到所對應的兒子指標為

空,或已經是葉子結點;

B-樹的特性:
1.關鍵字集合分佈在整顆樹中;

2.任何一個關鍵字出現且只出現在一個結點中;

3.搜尋有可能在非葉子結點結束;

4.其搜尋效能等價於在關鍵字全集內做一次二分查詢;

5.自動層次控制;

B+樹
B+ 樹是一種樹資料結構,是一個n叉樹,每個節點通常有多個孩子,一棵B+樹包含根節點、內部節點和葉子節點。根節點可能是一個葉子節點,也可能是一個包含兩個或兩個以上孩子節點的節點。

用途:
B+ 樹通常用於資料庫和作業系統的檔案系統中。NTFS, ReiserFS, NSS, XFS, JFS, ReFS 和BFS等檔案系統都在使用B+樹作為元資料索引。B+ 樹的特點是能夠保持資料穩定有序,其插入與修改擁有較穩定的對數時間複雜度。B+ 樹元素自底向上插入。

B+樹的定義
B+樹是應檔案系統所需而出的一種B-樹的變型樹。一棵m階的B+樹和m階的B-樹的差異在於:
1.有n棵子樹的結點中含有n個關鍵字,每個關鍵字不儲存資料,只用來索引,所有資料都儲存在葉子節點。

2.所有的葉子結點中包含了全部關鍵字的資訊,及指向含這些關鍵字記錄的指標,且葉子結點本身依關鍵字的大小自小而大順序連結。

3.所有的非終端結點可以看成是索引部分,結點中僅含其子樹(根結點)中的最大(或最小)關鍵字。 
通常在B+樹上有兩個頭指標,一個指向根結點,一個指向關鍵字最小的葉子結點。

B+樹是B-樹的變體,也是一種多路搜尋樹:
1.其定義基本與B-樹同,除了:

2.非葉子結點的子樹指標與關鍵字個數相同;

3.非葉子結點的子樹指標P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹

(B-樹是開區間);

5.為所有葉子結點增加一個鏈指標;

6.所有關鍵字都在葉子結點出現;

如:(M=3)

這裡寫圖片描述 

B+的搜尋與B-樹也基本相同,區別是B+樹只有達到葉子結點才命中(B-樹可以在

非葉子結點命中),其效能也等價於在關鍵字全集做一次二分查詢;

B+的特性:
1.所有關鍵字都出現在葉子結點的連結串列中(稠密索引),且連結串列中的關鍵字恰好

是有序的;

2.不可能在非葉子結點命中;

3.非葉子結點相當於是葉子結點的索引(稀疏索引),葉子結點相當於是儲存

(關鍵字)資料的資料層;

4.更適合檔案索引系統;

B*樹:
是B+樹的變體,在B+樹的非根和非葉子結點再增加指向兄弟的指標;
這裡寫圖片描述

B*樹定義了非葉子結點關鍵字個數至少為(2/3)*M,即塊的最低使用率為2/3
(代替B+樹的1/2);

B+樹的分裂:當一個結點滿時,分配一個新的結點,並將原結點中1/2的資料

複製到新結點,最後在父結點中增加新結點的指標;B+樹的分裂隻影響原結點和父

結點,而不會影響兄弟結點,所以它不需要指向兄弟的指標;

B*樹的分裂:當一個結點滿時,如果它的下一個兄弟結點未滿,那麼將一部分

資料移到兄弟結點中,再在原結點插入關鍵字,最後修改父結點中兄弟結點的關鍵字

(因為兄弟結點的關鍵字範圍改變了);如果兄弟也滿了,則在原結點與兄弟結點之

間增加新結點,並各複製1/3的資料到新結點,最後在父結點增加新結點的指標;

所以,B*樹分配新結點的概率比B+樹要低,空間使用率更高;

小結:
B-樹:
多路搜尋樹,每個結點儲存M/2到M個關鍵字,非葉子結點儲存指向關鍵

字範圍的子結點;

所有關鍵字在整顆樹中出現,且只出現一次,非葉子結點可以命中;

B+樹:
在B-樹基礎上,為葉子結點增加連結串列指標,所有關鍵字都在葉子結點

中出現,非葉子結點作為葉子結點的索引;B+樹總是到葉子結點才命中;

B*樹:
在B+樹基礎上,為非葉子結點也增加連結串列指標,將結點的最低利用率

從1/2提高到2/3;