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樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則,如果查詢關鍵字比結點關鍵字小,就進...