B-樹:
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、棗陽網(wǎng)絡(luò)推廣、微信小程序開發(fā)、棗陽網(wǎng)絡(luò)營銷、棗陽企業(yè)策劃、棗陽品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供棗陽建站搭建服務(wù),24小時服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com
一種適合外查找的平衡多叉樹(有些地方寫的是B-樹,注意不要誤讀 成"B減樹") 。
M階的B樹滿足如下性質(zhì):
1、根節(jié)點至少有兩個孩子;
2、每個非根節(jié)點有[[M/2],M]個孩子;
3、每個非根節(jié)點有[[M/2],M-1]個關(guān)鍵字,并且以升序排列;
4、key[i]和key[i+1]之間的孩子節(jié)點的值介于key[i]和key[i+1]之間;
5、所有的葉子節(jié)點都在同一層。
M階的B樹----M=3
插入:
如果插入值后,該節(jié)點的關(guān)鍵字的個數(shù)大于規(guī)定的要求,則需要調(diào)整,即分裂(新創(chuàng)建一個節(jié)點,把位于關(guān)鍵字序列中的中位數(shù)(不包含中位數(shù))以后的值包括子樹都拷貝到新建的節(jié)點中,將中位數(shù)提出成樹的根節(jié)點,中位數(shù)以前的值將成為中位數(shù)的左子樹,后半部分成為右子樹),如下圖:
應(yīng)用:運用于數(shù)據(jù)庫和文件系統(tǒng)。
具體實現(xiàn)代碼如下:
#pragma once
//使用外查找的平衡多叉樹
//性質(zhì):
// 1、根節(jié)點至少有兩個孩子
// 2、每個非根節(jié)點有[[M/2],M]個孩子
// 3、每個非根節(jié)點有[[M/2],M-1]個關(guān)鍵字,并且以升序排列
// 4、key[i]和key[i+1]之間的孩子節(jié)點的值介于key[i]和key[i+1]之間
// 5、所有的葉子節(jié)點都在同一層
template
struct BTreeNode
{
K _key[M];//關(guān)鍵字的個數(shù)為M-1,多留一個位置可以更加方便的求取中位數(shù)
BTreeNode
BTreeNode
size_t _size;//數(shù)組中存放的有效關(guān)鍵字的個數(shù)
BTreeNode()
:_parent(NULL)
,_size(0)
{
for(int i = 0;i < M+1;++i)
{
_subs[i] = NULL;
}
}
};
template
struct Pair
{
K _first;
V _second;
Pair(const K& key = K(),const V& value = V())//缺省參數(shù),會調(diào)用默認(rèn)構(gòu)造函數(shù)
:_first(key)
,_second(value)
{ }
};
template
class BTree
{
typedef BTreeNode
public:
BTree()
:_root(NULL)
{ }
Pair
{
if(_root == NULL)
return Pair
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
int index = 0;
while (index < cur->_size)
{
if(key == cur->_key[index])
{
return Pair
}
else if(key < cur->_key[index])
{
break;
}
else
{
index++;
}
}
parent = cur;
cur = cur->_subs[index];
}
return Pair
//找完也沒找到,為了使得該情況下方便插入節(jié)點,因此返回panrent,插入節(jié)點插入在parent上
}
bool Insert(const K& key)//插入
{
//當(dāng)前無節(jié)點
if(_root == NULL)
{
_root = new Node;//開辟一個新的節(jié)點
_root->_key[0] = key;
_root->_subs[0] = NULL;
_root->_parent = NULL;
_root->_size++;
return true;
}
Pair
if(cur._second != -1)//找到,則返回false,不插入重復(fù)關(guān)鍵字
{
return false;
}
//在節(jié)點cur中插入key和sub
Node* str = cur._first;
K newKey = key;
Node* sub = NULL;
while (1)
{
_InsertKey(str,newKey,sub);
if(str->_size < M)//關(guān)鍵字的數(shù)量小于M,則正確,直接返回
return true;
//插入數(shù)據(jù)后,該節(jié)點的關(guān)鍵字的個數(shù)大于規(guī)定的數(shù)量,需要調(diào)整,進行分裂
int mid = (str->_size - 1)/2;
int index = 0;
Node* temp = new Node;
//先拷貝下標(biāo)為mid后的關(guān)鍵字
for(size_t i = mid + 1;i < str->_size;i++)
{
temp->_key[index++] = str->_key[i];
temp->_size++;
str->_key[i] = 0;
}
//接著拷貝下標(biāo)為mid的關(guān)鍵字的sub
index = 0;
for(size_t i = mid + 1;i <= str->_size;i++)
{
temp->_subs[index++] = str->_subs[i];
if(str->_subs[i] != NULL)
str->_subs[i]->_parent = temp;
}
//更改str的大小
str->_size = (str->_size - 1)/2;
if(str->_parent == NULL)
{
_root = new Node;
_root->_key[0] = str->_key[mid];
str->_key[mid] = 0;
_root->_subs[0] = str;
_root->_subs[1] = temp;
_root->_size = 1;
str->_parent = _root;
temp->_parent = _root;
return true;
}
else
{
newKey = str->_key[mid];
str->_key[mid] = 0;
sub = temp;
str = str->_parent;
}
}
}
void InOrder()
{
_InOrder(_root);
cout< } protected: void _InsertKey(Node* cur,const K& key,Node* sub) { int index = cur->_size - 1; while (index >= 0 && cur->_key[index] > key)//若插入的節(jié)點比改位置的值小,則需要移位 { cur->_key[index+1] = cur->_key[index]; cur->_subs[index+2] = cur->_subs[index+1]; --index; } //否則,直接插入 cur->_key[index + 1] = key; cur->_subs[index+2] = sub; if(sub != NULL) sub->_parent = cur; cur->_size++; } void _InOrder(Node* root) { if(root == NULL) return; for(int i = 0;i < root->_size;i++) { _InOrder(root->_subs[i]); cout< } _InOrder(root->_subs[root->_size]); } protected: Node* _root; }; void BTreeTest() { BTree int a[] = {53,75,139,49,145,36,101}; for(int i = 0;i < sizeof(a)/sizeof(a[i]);i++) { tree.Insert(a[i]); } tree.InOrder(); } 運行結(jié)果:
新聞標(biāo)題:平衡搜索樹之B-樹
本文路徑:http://weahome.cn/article/poceos.html