B-Tree(這兒可不是減號,就是常規(guī)意義的BTree)
是一種多路搜索樹:
1.定義任意非葉子結(jié)點(diǎn)最多只有M個兒子;且M>2;
2.根結(jié)點(diǎn)的兒子數(shù)為[2, M];
3.除根結(jié)點(diǎn)以外的非葉子結(jié)點(diǎn)的兒子數(shù)為[M/2, M];
4.每個結(jié)點(diǎn)存放至少M(fèi)/2-1(取上整)和至多M-1個關(guān)鍵字;(至少2個關(guān)鍵字)
5.非葉子結(jié)點(diǎn)的關(guān)鍵字個數(shù)=指向兒子的指針個數(shù)-1;
6.非葉子結(jié)點(diǎn)的關(guān)鍵字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
7.非葉子結(jié)點(diǎn)的指針:P[1], P[2], …, P[M];其中P[1]指向關(guān)鍵字小于K[1]的
子樹,P[M]指向關(guān)鍵字大于K[M-1]的子樹,其它P[i]指向關(guān)鍵字屬于(K[i-1], K[i])的子樹;
8.所有葉子結(jié)點(diǎn)位于同一層;
如:(M=3)
B-Tree的搜索,從根結(jié)點(diǎn)開始,對結(jié)點(diǎn)內(nèi)的關(guān)鍵字(有序)序列進(jìn)行二分查找,如果命中則結(jié)束,否則進(jìn)入查詢關(guān)鍵字所屬范圍的兒子結(jié)點(diǎn);重復(fù),直到所對應(yīng)的兒子指針為空,或已經(jīng)是葉子結(jié)點(diǎn);
B-樹的特性:
1.關(guān)鍵字集合分布在整顆樹中;
2.任何一個關(guān)鍵字出現(xiàn)且只出現(xiàn)在一個結(jié)點(diǎn)中;
3.搜索有可能在非葉子結(jié)點(diǎn)結(jié)束;
4.其搜索性能等價于在關(guān)鍵字全集內(nèi)做一次二分查找;
5.自動層次控制;
由于限制了除根結(jié)點(diǎn)以外的非葉子結(jié)點(diǎn),至少含有M/2個兒子,確保了結(jié)點(diǎn)的至少利用率,其最底搜索性能為:
其中,M為設(shè)定的非葉子結(jié)點(diǎn)最多子樹個數(shù),N為關(guān)鍵字總數(shù);
所以B-樹的性能總是等價于二分查找(與M值無關(guān)),也就沒有B樹平衡的問題;
由于M/2的限制,在插入結(jié)點(diǎn)時,如果結(jié)點(diǎn)已滿,需要將結(jié)點(diǎn)分裂為兩個各占M/2的結(jié)點(diǎn);刪除結(jié)點(diǎn)時,需將兩個不足M/2的兄弟結(jié)點(diǎn)合并;
B+Tree
B+Tree是B-Tree的變體,也是一種多路搜索樹:
1.其定義基本與B-樹同,除了:
2.非葉子結(jié)點(diǎn)的子樹指針與關(guān)鍵字個數(shù)相同;
3.非葉子結(jié)點(diǎn)的子樹指針P[i],指向關(guān)鍵字值屬于[K[i], K[i+1])的子樹
(B-樹是開區(qū)間);
5.為所有葉子結(jié)點(diǎn)增加一個鏈指針;
6.所有關(guān)鍵字都在葉子結(jié)點(diǎn)出現(xiàn);
如:(M=3)
B+Tree的搜索與B-Tree也基本相同,區(qū)別是B+Tree只有達(dá)到葉子結(jié)點(diǎn)才命中(B-樹可以在非葉子結(jié)點(diǎn)命中),其性能也等價于在關(guān)鍵字全集做一次二分查找;
B+Tree的特性:
1.所有關(guān)鍵字都出現(xiàn)在葉子結(jié)點(diǎn)的鏈表中(稠密索引),且鏈表中的關(guān)鍵字恰好是有序的;
2.不可能在非葉子結(jié)點(diǎn)命中;
3.非葉子結(jié)點(diǎn)相當(dāng)于是葉子結(jié)點(diǎn)的索引(稀疏索引),葉子結(jié)點(diǎn)相當(dāng)于是存儲(關(guān)鍵字)數(shù)據(jù)的數(shù)據(jù)層;
4.更適合文件索引系統(tǒng);
BTree*
是B+Tree的變體,在B+Tree的非根和非葉子結(jié)點(diǎn)再增加指向兄弟的指針;
BTree定義了非葉子結(jié)點(diǎn)關(guān)鍵字個數(shù)至少為(2/3)M,即塊的最低使用率為2/3(代替B+樹的1/2);
B+Tree的分裂:當(dāng)一個結(jié)點(diǎn)滿時,分配一個新的結(jié)點(diǎn),并將原結(jié)點(diǎn)中1/2的數(shù)據(jù)復(fù)制到新結(jié)點(diǎn),最后在父結(jié)點(diǎn)中增加新結(jié)點(diǎn)的指針;B+Tree的分裂只影響原結(jié)點(diǎn)和父結(jié)點(diǎn),而不會影響兄弟結(jié)點(diǎn),所以它不需要指向兄弟的指針;
BTree的分裂:當(dāng)一個結(jié)點(diǎn)滿時,如果它的下一個兄弟結(jié)點(diǎn)未滿,那么將一部分?jǐn)?shù)據(jù)移到兄弟結(jié)點(diǎn)中,再在原結(jié)點(diǎn)插入關(guān)鍵字,最后修改父結(jié)點(diǎn)中兄弟結(jié)點(diǎn)的關(guān)鍵字(因為兄弟結(jié)點(diǎn)的關(guān)鍵字范圍改變了);如果兄弟也滿了,則在原結(jié)點(diǎn)與兄弟結(jié)點(diǎn)之間增加新結(jié)點(diǎn),并各復(fù)制1/3的數(shù)據(jù)到新結(jié)點(diǎn),最后在父結(jié)點(diǎn)增加新結(jié)點(diǎn)的指針;
所以,BTree分配新結(jié)點(diǎn)的概率比B+Tree要低,空間使用率更高。