B树的删除(仅考虑阶数m>=3的情形)
在非叶节点中删除关键码,只需从关键码右侧指针指向的子树中寻找最小关键码(沿最左侧指针向下走到叶节点,叶节点最左侧关键码即是)替换该关键码,并从最小关键码所在叶节点删除该最小关键码即可。这样只讨论在叶节点中删除关键码。
在叶节点中删除给定关键码,先删去该关键码及其右侧空指针,然后若该叶节点为根节点,则删除操作结束(删除后的B树可能为空树),若该叶节点不为根节点且关键码数大于等于ceil(m/2)-1,则删除操作结束。若该叶节点不为根节点且关键码数等于ceil(m/2)-2,则令该叶节点为当前节点,然后
设删除过程中当前节点关键数等于ceil(m/2)-2.
若当前节点为根节点且关键码数为0,则令根节点指针指向根节点唯一子树,删除根节点,删除操作结束
若当前节点不为根节点,则若该节点有右兄弟节点且右兄弟节点关键码数大于等于ceil(m/2),则将父节点指向当前节点的指针右侧关键码下移至当前节点最右侧,将右兄弟节点最左侧指针移至当前节点最右侧,最后将右兄弟最左侧关键码上移至父节点指向其指针的左侧,删除操作结束。
否则若当前节点不为根节点,有左兄弟节点,且左兄弟节点关键码数大于等于ceil(m/2),则将父节点中指向当前节点的指针左侧关键码下移至当前节点最左端,左兄弟最右侧关键码上移至父节点中指向它的指针右侧关键码位置,左兄弟最右侧指针移至当前节点最左端,随后删除操作结束
否则若当前节点不为根节点,有右兄弟且右兄弟关键码数等于ceil(m/2)-1,则将父节点中指向当前节点的指针右侧关键码下移至当前节点最右侧,然后将右兄弟完整拼接至当前节点右侧,随后删除右兄弟节点和父节点中指向它的指针。此时父节点关键码子树数减一,若父节点为根节点且关键码数为0则回溯至父节点否则删除操作结束;若父节点不为根节点且关键码数大于等于ceil(m/2)-1,则删除操作结束;若父节点不为根节点且关键码数等于ceil(m/2)-2,则回溯至父节点
否则若当前节点不为根节点,有左兄弟,且左兄弟关键码数等于ceil(m/2)-1,则将父节点中指向当前节点的指针左侧关键码下移至当前节点最左端,左兄弟完整拼接至当前节点左侧,删除左兄弟和父节点中指向它的指针,此时父节点关键码子树数减一,若父节点为根节点且关键码数为0则回溯至父节点否则删除操作结束;若父节点不为根节点且关键码数大于等于ceil(m/2)-1,则删除操作结束;若父节点不为根节点且关键码数等于ceil(m/2)-2,则回溯至父节点
B树的插入(仅考虑阶数m>=3的情形)
在空树中插入直接新建根节点,两指针域置空,填入关键码,再令root指向根节点
若在非空树中插入
那么仅在叶节点上插入,通过搜索在叶节点中找到插入位置,将关键码和空指针构成的二元组插入至叶节点,若插入后叶节点关键码数小于等于m-1则插入结束,否则令叶节点为当前节点
现设插入过程中当前节点关键码数为m,若当前节点左兄弟节点关键码数小于m-1,则从当前节点取关键码子树放入左兄弟节点中,否则若当前节点右兄弟节点关键码数小于m-1则从当前节点取关键码子树放入右兄弟节点中
否则以当前节点从左至右第ceil(m/2)个关键码为分割点将当前节点分隔为左右两部分(即分割点左侧和右侧的部分),左侧分割部分为原当前节点,若原当前节点为根节点,则直接新建根节点,两指针域分别指向左右分割部分,中间关键码即为原当前节点第ceil(m/2)个关键码,令root指向新根节点插入结束。
若原当前节点不为根节点,则将右侧分割部分的指针和原当前节点第ceil(m/2)个关键码构成的二元组插入至父节点中原当前节点对应的二元组右侧,此时父节点关键码子树数增一,若父节点关键码数小于等于m-1则插入结束,若父节点关键码数等于m,则以父节点为当前节点,回溯处理
插入和删除的C++实现(如有错误欢迎指出)
#include <iostream>
#include <utility>
#include <stack>
#include <vector>
#include <algorithm>
#include <ctime>
#include <random>
using namespace std;
const int M = 4; //B树阶数
template <typename T>
struct BTreeNode
{
struct BranchNode
{
unsigned long long _key_num = 0;
BTreeNode* p;
vector<pair<T, BTreeNode<T>*>> keyptrmap; //节点数据域和指针域
BranchNode() :keyptrmap(), p(nullptr) {}
};
union
{
vector<T>* leaf_data;
BranchNode* branch_data;
};
enum flag { leaf, branch } NodeFlag; //节点标志叶节点or分支节点
BTreeNode(flag type_of_node)
{
NodeFlag = type_of_node;
if (type_of_node == branch)
{
branch_data = new BranchNode();
}
else
{
leaf_data = new vector<T>();
}
}
~BTreeNode()
{
if (NodeFlag == branch)
{
delete branch_data;
}
else
{
delete leaf_data;
}
}
};
template <typename T>
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> SearchBTreeNode(BTreeNode<T>* ptr, pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d) //返回值:尾后+fasle表示第一指针,尾后+true表示失败,非尾后+true即为对应指针
{
typename vector<pair<T, BTreeNode<T>*>>::iterator m; //实参pair:尾后+false表示从第一指针后一指针开始搜索,尾后+true表示从头搜索,非尾后+true表示从非尾后后一位置开始搜索
if (d.first == ptr->branch_data->keyptrmap.end())
{
if (d.second)
{
if (ptr->branch_data->p != nullptr)
return { d.first, false };
return { ptr->branch_data->keyptrmap.begin(), false };
}
m = ptr->branch_data->keyptrmap.begin();
}
else
{
m = d.first;
++m;
}
if (m == ptr->branch_data->keyptrmap.end() || m->second != nullptr)
{
return { m, true };
}
return { ptr->branch_data->keyptrmap.begin(), false };
}
template <typename T>
bool leafKeyFromSmallToBig(BTreeNode<T>* leaf)
{
typename vector<T>::iterator before = leaf->leaf_data->begin();
typename vector<T>::iterator after = before + 1;
for (; after != leaf->leaf_data->end(); before = after, ++after)
{
if (*before >= *after)
return false;
}
return true;
}
template <typename T>
bool isBTree(BTreeNode<T>* root) //判断给定多叉树是否为B树
{
struct memory
{
BTreeNode<T>* p;
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> direction;
T nodemin; //节点代表子树中最小值
memory(BTreeNode<T>* p, const pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>& d) :p(p), direction(d) {}
};
BTreeNode<T>* ptr = root;
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d;
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d.first = ptr->branch_data->keyptrmap.end();
d.second = true;
}
T min; //节点某子树中最小节点值
T max; //节点某子树中最大节点值
BTreeNode<T>* const dest = ptr;
stack<memory> arrange;
bool TF = false;
int level = 0;
int beforelevel = 0;
while (true)
{
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> result;
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf ? true : (result = SearchBTreeNode(ptr, d)) == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
if (ptr == dest)
{
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (1 <= ptr->leaf_data->size() && ptr->leaf_data->size() <= M - 1)
{
if (leafKeyFromSmallToBig(ptr))
return true;
cout << "根叶节点关键码没有从小到大排列,非B树" << endl;
return false;
}
else
{
cout << "当前树只有根节点,但根节点子树数量不符合要求,非B树" << endl;
return false;
}
}
else
{
if (1 <= ptr->branch_data->keyptrmap.size() && ptr->branch_data->keyptrmap.size() <= M - 1)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = ptr->branch_data->keyptrmap.end();
--temp;
if (min > temp->first)
{
return true;
}
else
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "当前树根节点子树数量不符合要求,非B树";
return false;
}
}
}
else
{
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf)
{
++level;
if (TF == false)
{
beforelevel = level;
TF = true;
}
else
{
if (level != beforelevel)
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
if ((M + 1) / 2 - 1 <= ptr->leaf_data->size() && ptr->leaf_data->size() <= M - 1)
{
if (leafKeyFromSmallToBig(ptr) == false)
{
cout << "当前树叶结点关键码没有从小到大排列,非B树" << endl;
return false;
}
if (arrange.top().direction == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(arrange.top().p->branch_data->keyptrmap.end(), false))
{
arrange.top().nodemin = *(ptr->leaf_data->begin());
}
min = *(ptr->leaf_data->begin());
max = *(--ptr->leaf_data->end());
}
else
{
cout << "当前树叶节点数量不符合要求,非B树" << endl;
return false;
}
}
else
{
if ((M + 1) / 2 - 1 <= ptr->branch_data->keyptrmap.size() && ptr->branch_data->keyptrmap.size() <= M - 1)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = ptr->branch_data->keyptrmap.end();
--temp;
if (min > temp->first)
{
min = arrange.top().nodemin;
arrange.pop();
if (arrange.top().direction == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(arrange.top().p->branch_data->keyptrmap.end(), false))
{
arrange.top().nodemin = min;
}
}
else
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "当前树分支节点子树数量不符合要求,非B树" << endl;
return false;
}
}
--level;
ptr = arrange.top().p;
d = arrange.top().direction;
}
}
else
{
if (result == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.begin(), false))
{
cout << "分支节点存在空子树,非B树" << endl;
return false;
}
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
arrange.push(memory(ptr, result));
ptr = ptr->branch_data->p;
++level;
}
else
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = result.first;
if (d.first == ptr->branch_data->keyptrmap.end())
{
if (!(max < temp->first))
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
if (!(max < temp->first && min > d.first->first))
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
arrange.top().direction = pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(temp, true);
ptr = temp->second;
}
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d = pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true);
}
}
}
}
template <typename T>
bool compare(const pair<T, BTreeNode<T>*>& left, const pair<T, BTreeNode<T>*>& right)
{
return left.first < right.first;
}
template <typename T>
typename vector<pair<T, BTreeNode<T>*>>::iterator Upper_Bound(const T& key, vector<pair<T, BTreeNode<T>*>>& list)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator left = list.begin();
typename vector<pair<T, BTreeNode<T>*>>::iterator right = list.end() - 1;
while (left <= right)
{
int d = right - left + 1;
typename vector<pair<T, BTreeNode<T>*>>::iterator mid;
if (d % 2 == 1)
{
mid = left + d / 2;
}
else
{
mid = left + (d / 2 - 1);
}
if (key <= (*mid).first)
{
if (mid == list.begin())
{
return left;
}
right = mid - 1;
}
else
{
left = mid + 1;
}
}
return left;
}
template <typename T>
pair<bool, typename vector<T>::iterator> BinarySearch(vector<T>& list, typename vector<T>::iterator left, typename vector<T>::iterator right, const T& key)
{
while (left <= right)
{
int d = right - left + 1;
typename vector<T>::iterator mid;
if (d % 2 == 1)
{
mid = left + d / 2;
}
else
{
mid = left + (d / 2 - 1);
}
if (key < *mid)
{
if (mid == list.begin())
{
return { false, left };
}
right = mid - 1;
}
else if (key > *mid)
{
left = mid + 1;
}
else
{
return { true, mid };
}
}
return { false, left };
}
template <typename T>
void increAncestorKeyNum(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback)
{
while (stackforback.empty() == false)
{
++stackforback.top().first->branch_data->_key_num;
stackforback.pop();
}
}
template <typename T>
void decreAncestorKeyNum(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback)
{
while (stackforback.empty() == false)
{
--stackforback.top().first->branch_data->_key_num;
stackforback.pop();
}
}
template <typename T>
unsigned long long getKeyNum(BTreeNode<T>* current)
{
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
return current->leaf_data->size();
}
else
{
return current->branch_data->_key_num;
}
}
template <typename T>
void decrKeyNum(BTreeNode<T>* current, const unsigned long long& decr_num)
{
current->branch_data->_key_num -= decr_num;
}
template <typename T>
void incrKeyNum(BTreeNode<T>* current, const unsigned long long& decr_num)
{
current->branch_data->_key_num += decr_num;
}
template <typename T>
bool afterAdjust(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>*& current)
{
if (stackforback.top().first->branch_data->keyptrmap.size() <= M - 1)
{
increAncestorKeyNum(stackforback);
return true;
}
current = stackforback.top().first;
incrKeyNum(current, 1);
stackforback.pop();
return false;
}
template <typename T>
void left_to_right_for_leaf(BTreeNode<T>* left, BTreeNode<T>* right, const typename vector<pair<T, BTreeNode<T>*>>::iterator& mid)
{
right->leaf_data->insert(right->leaf_data->begin(), mid->first);
mid->first = left->leaf_data->back();
left->leaf_data->pop_back();
}
template <typename T>
void right_to_left_for_leaf(BTreeNode<T>* left, BTreeNode<T>* right, const typename vector<pair<T, BTreeNode<T>*>>::iterator& mid)
{
left->leaf_data->push_back(mid->first);
mid->first = *(right->leaf_data->begin());
right->leaf_data->erase(right->leaf_data->begin());
}
template <typename T>
void left_to_right_for_branch(BTreeNode<T>* left, BTreeNode<T>* right, const typename vector<pair<T, BTreeNode<T>*>>::iterator& mid)
{
right->branch_data->keyptrmap.insert(right->branch_data->keyptrmap.begin(), make_pair(mid->first, right->branch_data->p));
right->branch_data->p = left->branch_data->keyptrmap.back().second;
mid->first = left->branch_data->keyptrmap.back().first;
left->branch_data->keyptrmap.pop_back();
}
template <typename T>
void right_to_left_for_branch(BTreeNode<T>* left, BTreeNode<T>* right, const typename vector<pair<T, BTreeNode<T>*>>::iterator& mid)
{
left->branch_data->keyptrmap.push_back(make_pair(mid->first, right->branch_data->p));
mid->first = right->branch_data->keyptrmap.begin()->first;
right->branch_data->p = right->branch_data->keyptrmap.begin()->second;
right->branch_data->keyptrmap.erase(right->branch_data->keyptrmap.begin());
}
template <typename T>
bool toLeft(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
if (stackforback.top().second != stackforback.top().first->branch_data->keyptrmap.begin())
{
if (stackforback.top().second - 1 != stackforback.top().first->branch_data->keyptrmap.begin())
{
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
if ((stackforback.top().second - 2)->second->leaf_data->size() < M - 1)
{
right_to_left_for_leaf((stackforback.top().second - 2)->second, current, stackforback.top().second - 1);
increAncestorKeyNum(stackforback);
return true;
}
}
else
{
if ((stackforback.top().second - 2)->second->branch_data->keyptrmap.size() < M - 1)
{
decrKeyNum(current, getKeyNum(current->branch_data->p) + 1);
incrKeyNum((stackforback.top().second - 2)->second, getKeyNum(current->branch_data->p) + 1);
right_to_left_for_branch((stackforback.top().second - 2)->second, current, stackforback.top().second - 1);
increAncestorKeyNum(stackforback);
return true;
}
}
}
else
{
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (stackforback.top().first->branch_data->p->leaf_data->size() < M - 1)
{
right_to_left_for_leaf(stackforback.top().first->branch_data->p, current, stackforback.top().second - 1);
increAncestorKeyNum(stackforback);
return true;
}
}
else
{
if (stackforback.top().first->branch_data->p->branch_data->keyptrmap.size() < M - 1)
{
decrKeyNum(current, getKeyNum(current->branch_data->p) + 1);
incrKeyNum(stackforback.top().first->branch_data->p, getKeyNum(current->branch_data->p) + 1);
right_to_left_for_branch(stackforback.top().first->branch_data->p, current, stackforback.top().second - 1);
increAncestorKeyNum(stackforback);
return true;
}
}
}
}
return false;
}
template <typename T>
bool toRight(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
if (stackforback.top().second != stackforback.top().first->branch_data->keyptrmap.end())
{
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (stackforback.top().second->second->leaf_data->size() < M - 1)
{
left_to_right_for_leaf(current, stackforback.top().second->second, stackforback.top().second);
increAncestorKeyNum(stackforback);
return true;
}
}
else
{
if (stackforback.top().second->second->branch_data->keyptrmap.size() < M - 1)
{
left_to_right_for_branch(current, stackforback.top().second->second, stackforback.top().second);
decrKeyNum(current, getKeyNum(stackforback.top().second->second->branch_data->p) + 1);
incrKeyNum(stackforback.top().second->second, getKeyNum(stackforback.top().second->second->branch_data->p) + 1);
increAncestorKeyNum(stackforback);
return true;
}
}
}
return false;
}
template <typename T>
bool toLeftOrRight(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
if (toRight(stackforback, current))
return true;
if (toLeft(stackforback, current))
return true;
return false;
}
template <typename T>
pair<BTreeNode<T>*, bool> InsertBTree(BTreeNode<T>* root, const T& key) //B树插入函数
{
if (root == nullptr)
{
root = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
root->leaf_data->push_back(key);
return { root, true };
}
else
{
BTreeNode<T>* current = root;
stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>> stackforback;
while (current->NodeFlag == BTreeNode<T>::flag::branch)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator scankey = Upper_Bound(key, current->branch_data->keyptrmap);
if (scankey != current->branch_data->keyptrmap.end())
{
if (scankey->first == key)
{
cout << "关键码" << key << "已存在,插入失败" << endl;
return { root, false };
}
else
{
stackforback.push(make_pair(current, scankey));
if (scankey != current->branch_data->keyptrmap.begin())
{
--scankey;
current = scankey->second;
}
else
{
current = current->branch_data->p;
}
}
}
else
{
stackforback.push(make_pair(current, scankey));
--scankey;
current = scankey->second;
}
}
pair<bool, typename vector<T>::iterator> scankey = BinarySearch(*current->leaf_data, current->leaf_data->begin(), current->leaf_data->end() - 1, key);
if (scankey.first)
{
cout << "关键码" << key << "已存在,插入失败" << endl;
return { root, false };
}
else
{
current->leaf_data->insert(scankey.second, key);
}
if (current->leaf_data->size() <= M - 1)
{
increAncestorKeyNum(stackforback);
return { root, true };
}
else
{
if (stackforback.empty() == false)
{
if (toLeftOrRight(stackforback, current))
return { root, true };
}
unsigned long long Num = current->leaf_data->size();
BTreeNode<T>* ptr = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
ptr->leaf_data->insert(ptr->leaf_data->end(), current->leaf_data->end() - M / 2, current->leaf_data->end());
current->leaf_data->erase(current->leaf_data->end() - M / 2, current->leaf_data->end());
if (stackforback.empty() == true)
{
root = new BTreeNode<T>(BTreeNode<T>::flag::branch);
root->branch_data->_key_num = Num;
root->branch_data->p = current;
root->branch_data->keyptrmap.push_back(make_pair(current->leaf_data->back(), ptr));
current->leaf_data->pop_back();
return { root, true };
}
else
{
stackforback.top().first->branch_data->keyptrmap.insert(stackforback.top().second, make_pair(current->leaf_data->back(), ptr));
current->leaf_data->pop_back();
if (afterAdjust(stackforback, current))
return { root, true };
}
while (true)
{
if (stackforback.empty() == false)
{
if (toLeftOrRight(stackforback, current))
return { root, true };
}
BTreeNode<T>* ptr = new BTreeNode<T>(BTreeNode<T>::flag::branch);
ptr->branch_data->keyptrmap.insert(ptr->branch_data->keyptrmap.end(), current->branch_data->keyptrmap.end() - M / 2, current->branch_data->keyptrmap.end());
current->branch_data->keyptrmap.erase(current->branch_data->keyptrmap.end() - M / 2, current->branch_data->keyptrmap.end());
ptr->branch_data->p = current->branch_data->keyptrmap.back().second;
incrKeyNum(ptr, getKeyNum(ptr->branch_data->p) + ptr->branch_data->keyptrmap.size());
for (typename vector<pair<T, BTreeNode<T>*>>::iterator run = ptr->branch_data->keyptrmap.begin(); run != ptr->branch_data->keyptrmap.end(); ++run)
{
incrKeyNum(ptr, getKeyNum(run->second));
}
if (stackforback.empty() == true)
{
root = new BTreeNode<T>(BTreeNode<T>::flag::branch);
root->branch_data->_key_num = current->branch_data->_key_num;
decrKeyNum(current, getKeyNum(ptr) + 1);
root->branch_data->p = current;
root->branch_data->keyptrmap.push_back(make_pair(current->branch_data->keyptrmap.back().first, ptr));
current->branch_data->keyptrmap.pop_back();
return { root, true };
}
else
{
stackforback.top().first->branch_data->keyptrmap.insert(stackforback.top().second, make_pair(current->branch_data->keyptrmap.back().first, ptr));
current->branch_data->keyptrmap.pop_back();
decrKeyNum(current, getKeyNum(ptr) + 1);
if (afterAdjust(stackforback, current))
return { root, true };
}
}
}
}
}
template <typename T>
BTreeNode<T>* afterMerge(BTreeNode<T>* root, BTreeNode<T>*& current, stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback)
{
if (stackforback.top().first == root)
{
if (stackforback.top().first->branch_data->keyptrmap.size() == 0)
{
delete root;
return current;
}
decrKeyNum(root, 1);
return root;
}
if (stackforback.top().first->branch_data->keyptrmap.size() >= (M + 1) / 2 - 1)
{
decreAncestorKeyNum(stackforback);
return root;
}
current = stackforback.top().first;
decrKeyNum(current, 1);
stackforback.pop();
return nullptr;
}
template <typename T>
void beforeAdjust(typename vector<pair<T, BTreeNode<T>*>>::iterator& temp, const stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>*& ptr)
{
--temp;
if (temp != stackforback.top().first->branch_data->keyptrmap.begin())
{
typename vector<pair<T, BTreeNode<T>*>>::iterator before = temp - 1;
ptr = before->second;
}
else
{
ptr = stackforback.top().first->branch_data->p;
}
}
template <typename T>
bool borrowFromLeft(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp2 = stackforback.top().second;
if (temp2 != stackforback.top().first->branch_data->keyptrmap.begin())
{
BTreeNode<T>* ptr = nullptr;
if ((temp2 - 1) == stackforback.top().first->branch_data->keyptrmap.begin())
{
ptr = stackforback.top().first->branch_data->p;
}
else
{
ptr = (temp2 - 2)->second;
}
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (ptr->leaf_data->size() >= (M + 1) / 2)
{
left_to_right_for_leaf(ptr, current, temp2 - 1);
decreAncestorKeyNum(stackforback);
return true;
}
}
else
{
if (ptr->branch_data->keyptrmap.size() >= (M + 1) / 2)
{
left_to_right_for_branch(ptr, current, temp2 - 1);
incrKeyNum(current, getKeyNum(current->branch_data->p) + 1);
decrKeyNum(ptr, getKeyNum(current->branch_data->p) + 1);
decreAncestorKeyNum(stackforback);
return true;
}
}
}
return false;
}
template <typename T>
bool borrowFromRight(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = stackforback.top().second;
if (temp != stackforback.top().first->branch_data->keyptrmap.end())
{
BTreeNode<T>* ptr = temp->second;
if (current->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (ptr->leaf_data->size() >= (M + 1) / 2)
{
right_to_left_for_leaf(current, ptr, temp);
decreAncestorKeyNum(stackforback);
return true;
}
}
else
{
if (ptr->branch_data->keyptrmap.size() >= (M + 1) / 2)
{
incrKeyNum(current, getKeyNum(ptr->branch_data->p) + 1);
decrKeyNum(ptr, getKeyNum(ptr->branch_data->p) + 1);
right_to_left_for_branch(current, ptr, temp);
decreAncestorKeyNum(stackforback);
return true;
}
}
}
return false;
}
template <typename T>
bool borrowFromLeftOrRight(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current)
{
if (borrowFromRight(stackforback, current))
return true;
if (borrowFromLeft(stackforback, current))
return true;
return false;
}
template <typename T>
BTreeNode<T>* rebalanceAfterDelete(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>>& stackforback, BTreeNode<T>* current, BTreeNode<T>* root)
{
if (current == root)
{
if (current->leaf_data->empty() == true)
{
delete current;
return nullptr;
}
else
{
return current;
}
}
else
{
if (current->leaf_data->size() >= (M + 1) / 2 - 1)
{
decreAncestorKeyNum(stackforback);
return root;
}
else
{
BTreeNode<T>* ptr = nullptr;
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = stackforback.top().second;
if (borrowFromLeftOrRight(stackforback, current))
return root;
if (temp != stackforback.top().first->branch_data->keyptrmap.end())
{
current->leaf_data->push_back(temp->first);
current->leaf_data->insert(current->leaf_data->end(), temp->second->leaf_data->begin(), temp->second->leaf_data->end());
delete temp->second;
}
else
{
beforeAdjust(temp, stackforback, ptr);
ptr->leaf_data->push_back(temp->first);
ptr->leaf_data->insert(ptr->leaf_data->end(), current->leaf_data->begin(), current->leaf_data->end());
delete current;
current = ptr;
}
stackforback.top().first->branch_data->keyptrmap.erase(temp);
ptr = afterMerge(root, current, stackforback);
while (ptr == nullptr)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = stackforback.top().second;
if (borrowFromLeftOrRight(stackforback, current))
return root;
if (temp != stackforback.top().first->branch_data->keyptrmap.end())
{
current->branch_data->keyptrmap.push_back(make_pair(temp->first, temp->second->branch_data->p));
current->branch_data->keyptrmap.insert(current->branch_data->keyptrmap.end(), temp->second->branch_data->keyptrmap.begin(), temp->second->branch_data->keyptrmap.end());
incrKeyNum(current, getKeyNum(temp->second) + 1);
delete temp->second;
}
else
{
beforeAdjust(temp, stackforback, ptr);
ptr->branch_data->keyptrmap.push_back(make_pair(temp->first, current->branch_data->p));
ptr->branch_data->keyptrmap.insert(ptr->branch_data->keyptrmap.end(), current->branch_data->keyptrmap.begin(), current->branch_data->keyptrmap.end());
incrKeyNum(ptr, getKeyNum(current) + 1);
delete current;
current = ptr;
}
stackforback.top().first->branch_data->keyptrmap.erase(temp);
ptr = afterMerge(root, current, stackforback);
}
return ptr;
}
}
}
template <typename T>
void replaceDeletedValue(stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>> &stackforback, typename vector<pair<T, BTreeNode<T>*>>::iterator scankey, BTreeNode<T>* ¤t)
{
stackforback.push(make_pair(current, scankey + 1));
current = scankey->second;
while (current->NodeFlag == BTreeNode<T>::flag::branch)
{
stackforback.push(make_pair(current, current->branch_data->keyptrmap.begin()));
current = current->branch_data->p;
}
scankey->first = current->leaf_data->front();
}
template <typename T>
pair<BTreeNode<T>*, bool> DelBTree(BTreeNode<T>* root, const T& key) //B树删除函数
{
BTreeNode<T>* current = root;
stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>> stackforback;
bool replace = false;
while (current->NodeFlag == BTreeNode<T>::flag::branch)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator scankey = Upper_Bound(key, current->branch_data->keyptrmap);
if (scankey != current->branch_data->keyptrmap.end())
{
if (scankey->first == key)
{
replaceDeletedValue(stackforback, scankey, current);
current->leaf_data->erase(current->leaf_data->begin());
replace = true;
}
else
{
stackforback.push(make_pair(current, scankey));
if (scankey != current->branch_data->keyptrmap.begin())
{
--scankey;
current = scankey->second;
}
else
{
current = current->branch_data->p;
}
}
}
else
{
stackforback.push(make_pair(current, scankey));
--scankey;
current = scankey->second;
}
}
if (replace == false)
{
pair<bool, typename vector<T>::iterator> scankey = BinarySearch(*current->leaf_data, current->leaf_data->begin(), current->leaf_data->end() - 1, key);
if (scankey.first == true)
{
current->leaf_data->erase(scankey.second);
}
else
{
cout << "关键字" << key << "不存在,删除失败" << endl;
return { root, false };
}
}
return { rebalanceAfterDelete(stackforback, current, root), true };
}
template <typename T>
pair<BTreeNode<T>*, bool> DelKthKey(BTreeNode<T>* root, unsigned long long k, T& be_deleted) //删除B树中第K小的关键字
{
if (root == nullptr || getKeyNum(root) < k)
{
cout << "B树中不存在第" << k << "小元素,删除失败" << endl;
return { root, false };
}
BTreeNode<T>* current = root;
stack<pair<BTreeNode<T>*, typename vector<pair<T, BTreeNode<T>*>>::iterator>> stackforback;
bool repalce = false;
while (current->NodeFlag == BTreeNode<T>::flag::branch)
{
if (k <= getKeyNum(current->branch_data->p))
{
stackforback.push(make_pair(current, current->branch_data->keyptrmap.begin()));
current = current->branch_data->p;
continue;
}
k -= getKeyNum(current->branch_data->p);
typename vector<pair<T, BTreeNode<T>*>>::iterator scankey = current->branch_data->keyptrmap.begin();
while (scankey != current->branch_data->keyptrmap.end())
{
if (k == 1)
{
repalce = true;
be_deleted = scankey->first;
replaceDeletedValue(stackforback, scankey, current);
break;
}
else
{
--k;
if (k <= getKeyNum(scankey->second))
{
stackforback.push(make_pair(current, scankey + 1));
current = scankey->second;
break;
}
else
{
k -= getKeyNum(scankey->second);
++scankey;
}
}
}
}
if (repalce == false)
be_deleted = *(current->leaf_data->begin() + k - 1);
current->leaf_data->erase(current->leaf_data->begin() + k - 1);
return { rebalanceAfterDelete(stackforback, current, root), true };
}
int main()
{
const int N = 2000;
vector<int> seq(N);
for (int i = 0; i < N; ++i)
{
seq[i] = i + 1;
}
shuffle(seq.begin(), seq.end(), default_random_engine());
BTreeNode<int>* root = nullptr;
for (vector<int>::const_iterator p = seq.cbegin(); p != seq.cend(); ++p)
{
cout << "插入节点" << *p << endl;
auto r = InsertBTree(root, *p);
if (r.second)
{
cout << "插入成功" << endl;
}
else
{
cout << "插入失败" << endl;
exit(-1);
}
cout << endl;
root = r.first;
if (isBTree(root) == true)
{
cout << "当前树是B树";
cout << endl;
}
else
{
cerr << "错误当前树不是B树!" << endl;
exit(-1);
}
}
/*while (root != nullptr)
{
unsigned long long _size = getKeyNum(root);
unsigned long long test_k = rand() % (_size + 1);
if (test_k == 0)
test_k = 1;
cout << "删除第" << test_k << "小的元素" << endl;
int key;
auto r = DelKthKey(root, test_k, key);
if (r.second)
{
cout << "第" << test_k << "小的元素" << key << "删除成功" << endl;
}
else
{
cout << "第" << test_k << "小的元素删除失败" << endl;
exit(-1);
}
root = r.first;
if (root != nullptr)
{
if (isBTree(root) == true)
{
cout << "当前树是B树";
cout << endl;
}
else
{
cerr << "错误当前树不是B树!" << endl;
exit(-1);
}
}
else
cout << "NULL";
}*/
/*for (int i = N; i >= 1; --i)
{
cout << "删除第" << i << "小的元素" << endl;
int key;
auto r = DelKthKey(root, i, key);
if (r.second)
{
cout << "第" << i << "小的元素" << key << "删除成功" << endl;
}
else
{
cout << "第" << i << "小的元素删除失败" << endl;
exit(-1);
}
root = r.first;
if (root != nullptr)
{
if (isBTree(root) == true)
{
cout << "当前树是B树";
cout << endl;
}
else
{
cerr << "错误当前树不是B树!" << endl;
exit(-1);
}
}
else
{
cout << "NULL";
}
}*/
cout << endl;
for (vector<int>::const_iterator p = seq.cbegin(); p != seq.cend(); ++p)
{
cout << "删除节点" << *p << endl;
auto r = DelBTree(root, *p);
if (r.second)
{
cout << "删除成功" << endl;
}
else
{
cout << "删除失败" << endl;
exit(-1);
}
cout << endl;
root = r.first;
if (root != nullptr)
{
if (isBTree(root) == true)
{
cout << "当前树是B树";
cout << endl;
}
else
{
cerr << "错误当前树不是B树!" << endl;
exit(-1);
}
}
else
cout << "NULL";
cout << endl;
}
return 0;
}