1. 程式人生 > >樹形索引(B-樹查詢、插入、刪除)

樹形索引(B-樹查詢、插入、刪除)

一、B-樹定義

B-樹上每個節點包含多個關鍵碼從小到大排序,是一種平衡的多路查詢樹。最底層節點稱為外節點或葉結點,一般可省略。除了外結點,B-樹上的節點還有終端結點(葉結點的上一層)和非終端結點(終端結點層以上的結點)。

一顆m階B-樹,或為空樹,或為滿足下列特性的m叉樹:

(1)樹中每個結點最多有m顆子樹

(2)若根節點不是空節點(或根節點不是葉結點),子樹個數2~m

(3)除根節點和外節點之外的每個結點,子樹個數[m/2](向上取整)~m

(4)除外結點之外的每個結點中都包含下列資訊資料:(n,A0,K1,A1,K2,A2,...,Kn,An),n為結點中關鍵碼的個數,Ki為關鍵碼,i=1,2...,n,且Ki<K(i+1),i=1,2,...,n-1。

若該節點為根節點,則1<=n<=m-1,否則,[m/2]向上取整<=n<=m-1。若該結點為終端節點,則Ai,i=0,1,...,n為指向外結點的指標,即空指標。若該結點為根或非終端結點,則Ai為指向子樹根節點的指標,指標Ai-1所指子樹中所有結點的關鍵碼均小於Ki,指標Ai所指子樹中所有節點的關鍵碼均大於Ki。

(5)所有外結點都出現在同一層次上,並且不帶資訊。

根節點關鍵字個數 1~m-1(根非葉子),非根結點關鍵字個數 m/2向上取整-1~m-1

二、B-樹的查詢

(1)在B-樹中找結點

(2)在節點中找關鍵碼

B-樹通常存在磁碟上,則前一查詢操作是在磁碟上進行的,後一查詢操作在記憶體中進行

,,即在磁碟上找到指標p所指結點後,先將結點中資訊讀入記憶體,然後,再利用順序查詢或二分查詢查詢等於K的關鍵碼。顯然,在磁碟上進行一次查詢比在記憶體上進行一次查詢耗時,故,在磁碟上進行查詢的次數,即待查關鍵碼所在結點在B-樹的層次數,是決定B-樹查詢效率的首要因素

[m/2]為向上取整。討論深度為l+1的m階B-樹所具有的最少結點數。

第一層至少有1個結點,第二層至少有2個結點,由於除根結點外每個非葉結點至少有[m/2]顆子樹,則第三層至少有2[m/2]個結點,第四層至少有2[m/2]^2個結點,....,以此類推,第l+1層至少有2[m/2]^(l-1)個結點,而l+1層為外結點。若m階B-樹有n個關鍵碼,則外結點即查詢不成功的節點數位n+1,故

n+1>=2([m/2])^(l-1),l<=log[m/2](n+1)/2+1。在含有n個結點的B-樹上查詢時,從根節點到關鍵碼所在結點的路徑上結點數不超過

l=log[m/2](n+1)/2+1,這就是n個關鍵碼m階B-樹實際最大深度。

三、B-樹的插入

首先在某個終端結點中插入一個關鍵碼,若該結點關鍵碼個數<=m-1,插入完成,若超過m-1,即插入後結點中關鍵碼個數為m時,則要對該結點進行分裂操作,使得結點中關鍵碼個數滿足[m/2]-1<=n<=m-1。

a.利用前述的B-樹的查詢演算法查詢關鍵字的插入位置。若找到,則說明該關鍵字已經存在,直接返回。否則查詢操作必失敗於某個最低層的終端結點上。

b.判斷該結點是否還有空位置。即判斷該結點的關鍵字總數滿足n<m-1,則直接把關鍵字k插入到該結點的合適位置上。若不滿足,說明該結點己沒有空位置,需要把結點分裂成兩個。

分裂的方法是:生成一新結點。把原結點上的關鍵字和k按升序排序後,從中間位置把關鍵字(不包括中間位置的關鍵字)分成兩部分左部分所含關鍵字放在舊結點中右部分所含關鍵字放在新結點中,中間位置的關鍵字連同新結點的儲存位置插入到父結點中。如果父結點的關鍵字個數也超過(m-1),則要再分裂,再往上插。直至這個過程傳到根結點為止。

以3階B-樹為例:



四、B-樹的刪除

首先找到要刪除的關鍵碼所在結點,假設所刪關鍵碼為非終端結點中Ki,則可用指標Ai所指子樹中最小關鍵碼Y代替Ki,然後在相應終端結點中刪去Y,這樣就轉為刪除終端結點中的關鍵碼的問題了。

刪除終端節點中關鍵碼:

(1)被刪關鍵碼所在結點中的關鍵碼個數>=[m/2],說明刪去該關鍵字後該結點仍滿足B-樹的定義。這種情況最為簡單,只需從該結點中直接刪去關鍵字即可。

(2)被刪關鍵碼所在結點中關鍵碼個數n=[m/2]-1說明刪去該關鍵字後該結點將不滿足B-樹的定義,需要調整。

調整過程為:如果其左右兄弟結點中有“多餘”的關鍵字,即與該結點相鄰的右(左)兄弟結點中的關鍵字數目大於[m/2]-1。則可將右(左)兄弟結點中最小(大)關鍵字上移至雙親結點。而將雙親結點中小(大)於該上移關鍵字的最大(小)關鍵字下移至被刪 關鍵字所在結點中。

(3)被刪關鍵碼所在結點和其相鄰的左右兄弟節點中的關鍵碼個數均等於[m/2]-1,左右兄弟都不夠借。

需把要刪除關鍵字的結點與其左(或右)兄弟結點以及雙親結點中分割二者的關鍵字合併成一個結點,即在刪除關鍵字後,該結點中剩餘的關鍵字加指標,加上雙親結點中的關鍵字Ki一起合併到Ai(即雙親結點指向該刪除關鍵字結點的左(右)兄弟結點的指標)所指的兄弟結點中去。如果因此使雙親結點中關鍵字個數小於[m/2]-1,則對此雙親結點做同樣處理。以致於可能直到對根結點做這樣的處理而使整個樹減少一層。

總之,設所刪關鍵字為非終端結點中的Ki,則可以指標Ai所指子樹中的最小關鍵字Y代替Ki,然後在相應結點中刪除Y。對任意關鍵字的刪除都可以轉化為對最下層關鍵字的刪除。


a被刪關鍵字Ki所在結點的關鍵字數目不小於ceil(m/2),則只需從結點中刪除Ki和相應指標Ai,樹的其它部分不變


    b、被刪關鍵字Ki所在結點的關鍵字數目等於ceil(m/2)-1,則需調整。調整過程如上面所述。

    c、被刪關鍵字Ki所在結點和其相鄰兄弟結點中的的關鍵字數目均等於[m/2]-1,假設該結點有右兄弟,且其右兄弟結點地址由其雙親結點指標Ai所指。則在刪除關鍵字之後,它所在結點的剩餘關鍵字和指標,加上雙親結點中的關鍵字Ki一起,合併到Ai所指兄弟結點中(若無右兄弟,則合併到左兄弟結點中)。如果因此使雙親結點中的關鍵字數目少於[m/2]-1,則依次類推.