/*
b 树
B树也称B-树,它是一颗多路平衡查找树。我们描述一颗B树时需要指定它的阶数,阶数表示了一个结点最多有多少个孩子结点,一般用字母m表示阶数。当m取2时,就是我们常见的二叉搜索树。
一颗m阶的B树定义如下:
1)每个结点最多有m-1个关键字。
2)根结点最少可以只有1个关键字。
3)非根结点至少有Math.ceil(m/2)-1个关键字。
4)每个结点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
5)所有叶子结点都位于同一层,或者说根结点到每个叶子结点的长度都相同。
//说明
5阶b树 最多有5个有效的孩子节点 4个关键字
最少有 ceil(5/2) - 1 = 2个关键字
节点个数并没有限制 只要叶子节点在同一层
*/
template<typename T>
struct BTreeNode
{
BTreeNode()
{
m_data.clear();
m_list.clear();
}
vector<T> m_data;
vector<BTreeNode *> m_list;
};
template<typename T>
class BTree
{
public:
BTree(int stage) :m_root(new BTreeNode<T>()), m_stage(stage), m_minPoint(static_cast<int>(ceil(stage / 2.0))), m_minKey(m_minPoint - 1){
//二叉树 就不要搞过来了
if (stage < 3)
{
m_stage = 2;
m_minPoint = 1;
m_minKey = 1;
}
}
void Insert(T value);
void CheckNode(BTreeNode<T> *node);
void Delete(T value);
void Delete_ex(BTreeNode<T> * node,int value);
void Print(BTreeNode<T> * tRoot, int len);
public:
BTreeNode<T> * m_root;
int m_stage;
int m_minPoint;
int m_minKey;
};
template<typename T>
void BTree<T>::Insert(T value)
{
BTreeNode<T> *first = m_root;
vector<int>::iterator it;
while (first)
{
it = upper_bound(first->m_data.begin(), first->m_data.end(), value);
int index = it - first->m_data.begin();
if (first->m_list.begin() + index == first->m_list.end() || first->m_list[index] == nullptr)
{
first->m_data.insert(it, value);
first->m_list.insert(first->m_list.begin() + index, nullptr);
break;
}
else{
first = first->m_list[index];
}
}
CheckNode(first);
}
template<typename T>
void BTree<T>::CheckNode(BTreeNode<T> *node)
{
if (node == nullptr) return;
//需要分裂
if (node->m_data.size() >= m_stage)
{
int mid = node->m_data.size()/2;
BTreeNode<T> *temp1 = new BTreeNode<T>();
BTreeNode<T> *temp2 = new BTreeNode<T>();
temp1->m_data.insert(temp1->m_data.end(),node->m_data.begin(), node->m_data.begin() + mid);
temp1->m_list.insert(temp1->m_list.end(),node->m_list.begin(), node->m_list.begin() + mid+1);
temp2->m_data.insert(temp2->m_data.end(), node->m_data.begin() + mid + 1, node->m_data.end());
temp2->m_list.insert(temp2->m_list.end(), node->m_list.begin() + mid + 1, node->m_list.end());
T t = node->m_data[mid];
if (node == m_root)
{
node->m_data.clear();
node->m_data.push_back(t);
node->m_list.clear();
node->m_list.push_back(temp1);
node->m_list.push_back(temp2);
}
else{
//找父节点
BTreeNode<T> *father = m_root;
while (father)
{
if (find(father->m_list.begin(), father->m_list.end(), node) != father->m_list.end())
break;
auto it = upper_bound(father->m_data.begin(), father->m_data.end(), t);
int index = it - father->m_data.begin();
father = father->m_list[index];
}
auto it = find(father->m_list.begin(), father->m_list.end(), node);
int index = it - father->m_list.begin();
(*it) = temp2;
father->m_data.insert(father->m_data.begin() + index, t);
father->m_list.insert(father->m_list.begin() + index, temp1);
CheckNode(father);
}
}
}
template<typename T>
void BTree<T>::Delete(T value)
{
BTreeNode<T> *first = m_root;
vector<int>::iterator it;
while (first)
{
it = upper_bound(first->m_data.begin(), first->m_data.end(), value, less_equal<>());
if (it != first->m_data.end() && (*it) == value)
{
break;
}
else{
int index = it - first->m_data.begin();
first = first->m_list[index];
}
}
if (first == nullptr) return;
//非叶子节点转化为叶子节点
if (find_if(first->m_list.begin(), first->m_list.end(), bind2nd(not_equal_to<BTreeNode<T> *>(), nullptr)) != first->m_list.end())
{
BTreeNode<T> *next = first;
int index = it - first->m_data.begin();
for (int i = index; i >= 0; i--)
{
if (next->m_list[i] != nullptr)
{
next = next->m_list[i];
break;
}
}
if (first == next)
{
cout << "非叶子节点转化为叶子节点 Error" << endl;
return;
}
while (next)
{
auto tem = find_if(next->m_list.rbegin(), next->m_list.rend(), bind2nd(not_equal_to<BTreeNode<T> *>(), nullptr));
if (tem != next->m_list.rend())
{
next = (*tem);
}
else
break;
}
if (next == nullptr)
{
cout << "非叶子节点转化为叶子节点 Error 2" << endl;
return;
}
swap((*it), next->m_data.back());
first = next;
it = next->m_data.end() - 1;
}
int ttt = it - first->m_data.begin();
first->m_data.erase(it);
first->m_list.erase(first->m_list.begin() + ttt);
Delete_ex(first,value);
}
template <typename T>
void BTree<T>::Delete_ex(BTreeNode<T> * first,int value)
{
if (first == nullptr) return;
if (first->m_data.size() >= m_minKey)
{
}
else{
//找父节点
BTreeNode<T> *father = nullptr;
int index = -1;
if (first != m_root)
{
if (first->m_data.size() > 0)
{
father = m_root;
value = first->m_data[0];
while (father)
{
if (find(father->m_list.begin(), father->m_list.end(), first) != father->m_list.end())
break;
auto fait = upper_bound(father->m_data.begin(), father->m_data.end(), value, less_equal<>());
int index = fait - father->m_data.begin();
father = father->m_list[index];
}
}
else{
//至少要5阶以上才不会走这里 5阶至少有2个数据节点
deque<BTreeNode<T> *> templist = { m_root };
BTreeNode<T> *findFather = nullptr;
while (templist.size() > 0)
{
int len = templist.size();
for (int i = 0; i < len; i++)
{
findFather = templist.front(); templist.pop_front();
if (find(findFather->m_list.begin(), findFather->m_list.end(), first) != findFather->m_list.end())
{
father = findFather;
break;
}
//第一个大于value的位置
auto fait = upper_bound(findFather->m_data.begin(), findFather->m_data.end(), value, less_equal<>());
int index = fait - findFather->m_data.begin();
if (index - 1 >= 0 && index - 1 < findFather->m_list.size())
{
if (findFather->m_list[index - 1])
templist.push_back(findFather->m_list[index - 1]);
}
if (index < findFather->m_list.size())
{
if (findFather->m_list[index])
templist.push_back(findFather->m_list[index]);
}
}
}
}
}
if (father == nullptr)
{
int nCount = first->m_data.size();
for (int i = 0; i < first->m_list.size(); i++)
{
if (first->m_list[i] != nullptr)
{
nCount += first->m_list[i]->m_data.size();
}
}
if (nCount < m_stage)
{
for (int i = 0; i < first->m_list.size(); i++)
{
if (first->m_list[i] != nullptr)
{
BTreeNode<T> *temp = first->m_list[i];
first->m_data.insert(first->m_data.begin() + i, temp->m_data.begin(), temp->m_data.end());
}
}
for (auto it = first->m_list.begin(); it != first->m_list.end(); )
{
if ((*it) != nullptr)
{
BTreeNode<T> *temp = (*it);
it = first->m_list.erase(it);
it = first->m_list.insert(it, temp->m_list.begin(), temp->m_list.end());
it += temp->m_list.size();
delete temp;
temp = nullptr;
}
else
it++;
}
}
return;
}
index = find(father->m_list.begin(), father->m_list.end(), first) - father->m_list.begin();
BTreeNode<T> *left = nullptr, *right = nullptr;
//左兄弟
if (index - 1 >= 0)
{
left = father->m_list[index - 1];
if (left != nullptr)
{
if (left->m_data.size() > m_minKey)
{
first->m_data.insert(first->m_data.begin(), father->m_data[index - 1]);
first->m_list.insert(first->m_list.begin(), left->m_list.back());
father->m_data[index - 1] = left->m_data.back();
left->m_data.pop_back();
left->m_list.pop_back();
return;
}
}
}
//右兄弟
if (index + 1 < father->m_list.size())
{
right = father->m_list[index + 1];
if (right)
{
if (right->m_data.size() > m_minKey)
{
first->m_data.push_back( father->m_data[index]);
first->m_list.push_back(right->m_list.front());
father->m_data[index] = right->m_data.front();
right->m_data.erase(right->m_data.begin());
right->m_list.erase(right->m_list.begin());
return;
}
}
}
//都没的借 合并
if (left)
{
value = father->m_data[index - 1];
first->m_data.insert(first->m_data.begin(), father->m_data[index - 1]);
first->m_data.insert(first->m_data.begin(), left->m_data.begin(), left->m_data.end());
first->m_list.insert(first->m_list.begin(), left->m_list.begin(), left->m_list.end());
father->m_data.erase(father->m_data.begin() + index - 1);
father->m_list.erase(father->m_list.begin() + index - 1);
//if (first->m_list.size() > first->m_data.size() + 1 && first->m_list.back() == nullptr) first->m_list.pop_back();
}
else if (right)
{
value = father->m_data[index];
right->m_data.insert(right->m_data.begin(), father->m_data[index]);
right->m_data.insert(right->m_data.begin(), first->m_data.begin(), first->m_data.end());
right->m_list.insert(right->m_list.begin(), first->m_list.begin(), first->m_list.end());
//if (right->m_list.size() > right->m_data.size() + 1 && right->m_list.back() == nullptr) right->m_list.pop_back();
father->m_data.erase(father->m_data.begin() + index);
father->m_list.erase(father->m_list.begin() + index);
}
else{
}
Delete_ex(father,value);
}
}
template <typename T>
void BTree<T>::Print(BTreeNode<T> * tRoot, int len)
{
if (tRoot == nullptr)
return;
int t = -1;
if (tRoot != m_root && tRoot->m_data.size() == 0 && tRoot->m_list.size() <= 1)
{
cout << "xxx" << endl;
}
for (int i = 0; i < tRoot->m_data.size(); i++)
{
Print(tRoot->m_list[i], len + 1);
cout << tRoot->m_data[i] << " ";
t = i+1;
}
if (t > 0 && tRoot->m_list.size() > t)
Print(tRoot->m_list[t], len + 1);
}
int Rand(int a)
{
return rand() % a;
}
int main()
{
int a[200];
int b[21] = { 0, 7, 1, 17, 16, 19, 15, 2, 9, 6, 3, 12, 14, 5, 13, 11, 10, 8, 4, 18 };
int c[21] = { 0, 9, 5, 10, 8, 14, 6, 15, 11, 3, 16, 18, 4, 7, 17, 13, 12, 1, 19, 2};
srand(time(nullptr));
int nCount = 10000,nStart = 2,nEnd = 50;
while (nStart <= nEnd)
{
nCount = 100;
while (nCount--)
{
BTree<int> t(nStart);
for (int i = 1; i < 100; i++)
{
a[i] = i;
}
random_shuffle(a + 1, a + 100, Rand);
for (int i = 1; i < 100; i++)
{
t.Insert(a[i]);
}
for (int i = 1; i < 100; i++)
cout << a[i] << ",";
cout << endl << endl;
t.Print(t.m_root, 5);
cout << endl;
random_shuffle(a + 1, a + 100, Rand);
for (int i = 1; i < 100; i++)
cout << a[i] << ",";
cout << endl << endl;
for (int i = 1; i < 100; i++)
{
t.Delete(a[i]);
t.Print(t.m_root, 5);
cout << endl;
}
t.Print(t.m_root, 5);
cout << endl;
cout << nCount << endl;
}
++nStart;
}
return 0;
}