B樹 B TREE的實現

2021-06-13 11:01:21 字數 4934 閱讀 6847

b樹又叫平衡多路查詢樹,是一種組織和維護外存檔案系統非常有效的資料結構

一棵m階的b樹(m叉樹)的特性如下:

樹中每個結點最多含有m個孩子(m>=2);

除根結點和葉子結點外,其它每個結點至少有[ceil(m / 2)]=(m-1)/2個孩子(其中ceil(x)是乙個取上限的函式);

若根結點不是葉子結點,則至少有2個孩子(特殊情況:沒有孩子的根結點,即根結點為葉子結點,整棵樹只有乙個根節點);

所有葉子結點都出現在同一層,葉子結點不包含任何關鍵字資訊(可以看做是外部接點或查詢失敗的接點,

實際上這些結點不存在,指向這些結點的指標都為null);

每個非終端結點中包含有n個關鍵字資訊: (n,p0,k1,p1,k2,p2,......,kn,pn)。其中:

a)   ki (i=1...n)為關鍵字,且關鍵字按順序公升序排序k(i-1)< ki。 

b)   pi為指向子樹根的接點,且指標p(i-1)指向子樹種所有結點的關鍵字均小於ki,但都大於k(i-1)。 

c)   關鍵字的個數n必須滿足: (m-1)/2<= n <= m-1

* b樹的插入演算法

*將關鍵字k插入到b樹中分兩步進行:

(1)、利用前述的b樹的查詢演算法找出該關鍵字的插入結點(插入結點一定是葉子結點)

(2)、判斷該結點是否有空位置,即判斷該結點是有滿足n

直接插入即可(要保持該結點的關鍵字仍然有序);

若n=m-1,說明該結點已經沒有空位置,要將該結點**成兩個.**的做法是,取乙個

新結點,把原結點上的關鍵字和k按公升序排列,從中間位置((m+1)/2處)把關鍵字(

不包含中間關鍵字)**成兩部分,左部分所含關鍵字放在舊節點中,右部分所含關鍵

字放在新結點中,中間關鍵字連同新結點的位址插入到父節點中。

如果父節點的關鍵字數也滿了,那就向上繼續**,最多是做到把根節點也**,產生

新的根節點。

*//*

*b樹的刪除演算法

*要使得刪除後的結點滿足n>=(m-1)/2,將涉及到結點的"合併"問題。

*在b樹中刪除關鍵字k的過程分兩步完成:

(1)、查詢出該關鍵字所在結點

(2)、在結點上刪除關鍵字k分兩種情況:一是在葉子結點上刪除、二在非葉子結點上刪除

1)、在非葉子結點上刪除關鍵字k的過程:假設要刪除的關鍵字key[i],在刪去該關鍵

字後,以該結點的ptr[i]所指向的子樹中的最小關鍵字key[min]來代替被刪關鍵

字key[i]所在的位置(注意ptr[i]所指子樹中的最小關鍵字key[min]一定是在葉子

節點上),然後再也指標ptr[i]所指結點為根節點查詢並刪除key[min](即以ptr[i]

所指的結點為b樹的根節點,key[min]為刪除結點,然後呼叫b樹的刪除演算法),這樣

也就把在非葉子結點上刪除關鍵字k的問題轉化為在葉子結點上面刪除關鍵字key[min]的問題。

2)、在葉子結點上刪除關鍵字共分以下三種情況:

no.1:如果被刪除的結點的關鍵字數大於(m-1)/2,說明刪去該關鍵字後,該結點仍滿

足b樹的定義,可以直接刪除.

no.2:如果被刪除的結點的關鍵字數等於(m-1)/2,說明刪去該節點後關鍵字數將不滿足

b樹的定義,此時若該結點的左(或右)兄弟結點的關鍵字樹大於(m-1)/2,則把該

結點的左(或右)兄弟結點中最大(或最小)的關鍵字上移到雙親結點中,同時把雙

親結點中大於(或小於)上移關鍵字的關鍵字下移到要刪除的關鍵字結點中,這樣

刪去該關鍵字後,該結點的以及它的左(或右)兄弟仍滿足b樹的定義.

no.3:如果被刪除的結點的關鍵字數等於(m-1)/2,並且該結點的左右兄弟(如果存在的話)的關鍵字數目

也都為(m-1)/2,這時,需要刪除關鍵字的結點與其左(或右)兄弟結點以及雙親結點中分割二者的

關鍵字合併成乙個新的結點。如果因此雙親結點中的關鍵字數小於(m-1)/2,則對雙親節點做同樣

的處理,以至於可能對根結點做同樣的處理以至於整棵樹減少一層。

**如下:

#include#includeusing namespace std;

#define max_btnode 10

#define degree 4

struct btnode

//建構函式,初始化關鍵字數與是否為葉子標記

};class b_tree

;b_tree::b_tree()

void b_tree::b_tree_create()

void b_tree::b_tree_init(char *key,int length)

}void b_tree::b_tree_insert(char key)

else

b_tree_insert_nonfull(root,key);

}void b_tree::b_tree_insert_nonfull(btnode *_root,char key)

_root->key[i + 1] = key;

_root->keynum++;

} else

b_tree_insert_nonfull(_root->child[i],key); }}

void b_tree::b_tree_split_child(btnode *_root,int i,btnode *child)

newnode->keynum = j;

if(!newnode->leaf) }

child->keynum -= degree; //child的總數加上newnode的總數是2*degree - 2,中間那個**到父節點i處

for(j = _root->keynum - 1; j >= i; j--) //_root有keynum個關鍵字,從keynum-1開始往前逐個往後移動

_root->key[i] = child->key[child->keynum];

for(j = _root->keynum; j > i; j--) //_root有keynum+1個關鍵字,從keynum開始往前逐個往後移動

_root->child[i + 1] = newnode; //只需新增比新增節點的右孩子

_root->keynum++;

}btnode* b_tree::b_tree_search(btnode *_root,char key,int &location)

bool b_tree::b_tree_search_btnode(btnode *_root,char key,int &location)

void b_tree::b_tree_print_layer() //層次遍歷

} coutcout<<" ";

}void b_tree::b_tree_queuepush(btnode *_root,queue*btnqueue) }}

btnode* b_tree::b_tree_root()

void b_tree::b_tree_print_order(btnode *_root) }}

void b_tree::b_tree_delete(char key)

else

_root->keynum--;

}} else

deleteflag = b_tree_delete_nonless(_root->child[location],key); //如果在當前節點沒找到,繼續按照查詢路徑往下查詢

if(!_root->leaf) //依次往上檢查是否出現子節點的關鍵字不夠的情況

else if(location == _root->keynum - 1)

else

}} return deleteflag; }}

void b_tree::b_tree_move_from_left(btnode *_root,int location)

temp->key[i] = _root->key[location - 1];

temp->keynum++;

temp = _root->child[location - 1];

_root->key[location - 1] = temp->key[temp->keynum - 1];

_root->child[location]->child[i] = temp->child[temp->keynum];

temp->keynum--;

}void b_tree::b_tree_move_from_right(btnode *_root,int location)

temp->child[i - 1] = temp->child[i];

}void b_tree::b_tree_combine(btnode *_root,int location)

templeft->child[j] = tempright->child[i];

templeft->keynum = j;

_root->child[location + 1] = templeft;

for(i = location + 1; i < _root->keynum;i++)

_root->child[i - 1] = _root->child[i];

_root->keynum--;

delete tempright;

}int main()

; tree->b_tree_init(key,52);

tree->b_tree_print_layer();

tree->b_tree_search(tree->b_tree_root(),'j',location);

tree->b_tree_print_order(tree->b_tree_root());

tree->b_tree_delete('b');

tree->b_tree_print_layer();

return 0;

}

資料結構 B樹(B Tree)

b樹是乙個平衡的多路搜尋樹,每個節點可以儲存多個元素。對於m階b樹 m 2m 2 m 2 設其任意節點儲存元素的個數為x,那麼 舉些例子 當m 2時,非根節點子節點個數 1 y 21 leq y leq 2 1 y 2,故稱為 1,2 樹,就是二叉搜尋樹。當m 3時,非根節點子節點個數 2 y 32...

B樹(B tree, 平衡的多路查詢樹)的相關知識

目錄 多路搜尋樹 b樹 b 樹 首先,介紹一下2 3樹,指的是其中每乙個節點2結點 有兩個孩子或者3結點 三個孩子或者沒有孩子,2節點指的是該節點有乙個元素和兩個孩子or沒有孩子,3節點指的是該節點有兩個元素 一大一小 和三個孩子or沒有孩子。特點是所有葉子節點都在同一層,插入和刪除節點都必須保證順...

B樹 B 樹 B 樹 B 樹的區別

b樹 即二叉搜尋樹 1.所有非葉子結點至多擁有兩個兒子 left和right 2.所有結點儲存乙個關鍵字 3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹 如 b樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則,如果查詢關鍵字比結點關鍵字小,就進...