#include<iostream>
#include<cstdio>
#include<stdbool.h>
#include"bin_tree.h"
#include"vector.h"
using namespace std;
template<typename T> struct bt_node;
template<typename T> using bt_node_posi = bt_node<T>*;
template<typename T> struct bt_node
{
bt_node_posi<T> parent;
my_vector<T> key;
my_vector<bt_node_posi<T>> child;
bt_node()
{
child.insert(0, nullptr);
parent = nullptr;
}
bt_node(T e,bt_node_posi<T> lc=nullptr,bt_node_posi<T> rc=nullptr)
{
parent = nullptr;
key.insert(0, e);
child.insert(0, lc);
child.insert(1, rc);
if (lc) lc->parent = this;
if (rc) rc->parent = this;
}
};
template<typename T> class btree
{
protected:
bt_node_posi<T> root, phit;
int size;
int order;
void solve_overflow(bt_node_posi<T>);
void solve_underflow(bt_node_posi<T>);
public:
btree(int Order = 3, int s = 0) :order(Order), size(s)
{
root = new bt_node<T>();
}
~btree()
{
if (root) release(root);
}
int get_size() { return size; }
int get_order() { return order; }
bt_node_posi<T> get_root() { return root; }
bool empty() { if (size == 0) return true; else return false; }
void inorder_tra(bt_node_posi<T> ptr);
bt_node_posi<T> search(const T& e);
bool insert(const T& e);
bool remove(const T& e);
};
int cnt = 0;
template<typename T> void btree<T>::inorder_tra(bt_node_posi<T> ptr)
{
if (ptr == nullptr) return;
for (int i = 0; i < ptr->child.Size(); ++i) {
bt_node_posi<T> temp = ptr->child[i];
inorder_tra(temp);
if (i < ptr->key.Size()) {
cout << ptr->key[i] << " ";
}
}
}
template<typename T> bt_node_posi<T> btree<T>::search(const T& e)
{
bt_node_posi<T> ptr = root;
phit = nullptr;
while (ptr)
{
Rank r = ptr->key.search(e);
if (r>=0 && ptr->key[r] == e) return ptr;
else
{
phit = ptr;
ptr = ptr->child[r + 1];
}
}
return nullptr;
}
template<typename T> bool btree<T>::insert(const T& e)
{
if (search(e)) return false;
Rank r = phit->key.search(e);
phit->key.insert(r + 1, e);
phit->child.insert(r + 2, nullptr);
++size;
solve_overflow(phit);
return true;
}
template<typename T> bool btree<T>::remove(const T& e)
{
bt_node_posi<T> ptr = search(e);
if (!ptr) return false;
Rank r = ptr->key.search(e);
if (ptr->child[0] != nullptr)
{
bt_node_posi<T> suc = ptr->child[r + 1];
while (suc->child[0] != nullptr) suc = suc->child[0];
ptr->key[r] = suc->key[0];
ptr = suc;
r = 0;
}
ptr->key.remove(r);
ptr->child.remove(r + 1);
--size;
solve_underflow(ptr);
return true;
}
template<typename T> void btree<T>::solve_overflow(bt_node_posi<T> ptr)
{
do{
if (ptr->key.Size() < order) break;
int mid = order / 2;
bt_node_posi<T> rchild = new bt_node<T>();
my_vector<T> k(ptr->key, mid + 1, ptr->key.Size());
rchild->key = k;
ptr->key.remove(mid + 1, ptr->key.Size());
my_vector<bt_node_posi<T>> ch(ptr->child, mid + 1, ptr->child.Size());
rchild->child = ch;
ptr->child.remove(mid + 1, ptr->child.Size());
if (rchild->child[0])
for (int i = 0; i < rchild->child.Size() ; ++i)
rchild->child[i]->parent = rchild;
bt_node_posi<T> parent = ptr->parent;
if (parent != nullptr) {
Rank r = parent->key.search(ptr->key[mid]);
parent->key.insert(r + 1, ptr->key.remove(mid));
parent->child.insert(r + 2, rchild);
rchild->parent = parent;
}
else
{
parent = root = new bt_node<T>();
parent->key.insert(0, ptr->key.remove(mid));
parent->child[0] = ptr;
parent->child.insert(1, rchild);
ptr->parent = parent;
rchild->parent = parent;
}
ptr = ptr->parent;
}while (ptr != nullptr);
}
template<typename T> void btree<T>::solve_underflow(bt_node_posi<T> ptr)
{
bt_node_posi<T> parent;
do {
if (ptr->key.Size() >= order / 2)
return;
parent = ptr->parent;
Rank r = 0;
if (parent)
{
for (int i = 0; i < parent->child.Size(); ++i)
if (parent->child[i] == ptr)
r = i;
if (r >= 1 && parent->child[r - 1]->key.Size() > order / 2)
{
bt_node_posi<T> left = parent->child[r - 1];
ptr->key.insert(0, parent->key[r - 1]);
ptr->child.insert(0, left->child.remove(left->child.Size()-1));
if(ptr->child[0]) ptr->child[0]->parent = ptr;
parent->key[r - 1] = left->key.remove(left->key.Size() - 1);
}
else if (r<parent->child.Size() - 1 && parent->child[r + 1]->key.Size()>order / 2)
{
bt_node_posi<T> right = parent->child[r + 1];
ptr->key.insert(ptr->key.Size(), parent->key[r]);
ptr->child.insert(ptr->child.Size(), right->child.remove(0));
if (ptr->child[ptr->child.Size() - 1]) ptr->child[ptr->child.Size() - 1]->parent = ptr;
parent->key[r] = right->key.remove(0);
}
else
{
if (r == parent->key.Size() )
{
bt_node_posi<T> left = parent->child[r - 1];
left->key.insert(left->key.Size(), parent->key.remove(r - 1));
parent->child.remove(r);
for (int i = 0; i < ptr->key.Size(); ++i)
{
left->key.insert(left->key.Size(), ptr->key.remove(0));
left->child.insert(left->child.Size(), ptr->child.remove(0));
if (left->child[left->child.Size() - 1]) left->child[left->child.Size() - 1]->parent = left;
}
left->child.insert(left->child.Size(), ptr->child.remove(0));
if (left->child[left->child.Size() - 1]) left->child[left->child.Size() - 1]->parent = left;
release(ptr);
}
else
{
bt_node_posi<T> right = parent->child[r + 1];
ptr->key.insert(ptr->key.Size(), parent->key.remove(r));
parent->child.remove(r + 1);
for (int i = 0; i < right->key.Size(); ++i)
{
ptr->key.insert(ptr->key.Size(), right->key.remove(0));
ptr->child.insert(ptr->child.Size(), right->child.remove(0));
if (ptr->child[ptr->child.Size() - 1]) ptr->child[ptr->child.Size() - 1]->parent = ptr;
}
ptr->child.insert(ptr->child.Size(), right->child.remove(0));
if (ptr->child[ptr->child.Size() - 1]) ptr->child[ptr->child.Size() - 1]->parent = ptr;
release(right);
}
}
}
else
{
if (ptr->key.Size() == 0 && ptr->child[0] != nullptr)
{
root = ptr->child[0];
root->parent = nullptr;
ptr->child[0] = nullptr;
release(ptr);
}
}
ptr = parent;
} while (parent != nullptr);
}
int main()
{
btree<int> Btree(3);
for (int i = 1; i < 100; ++i)
{
Btree.insert(i);
}
Btree.inorder_tra(Btree.get_root());
cout << endl;
cout << "size=" << Btree.get_size() << endl;
for (int i = 0; i < 30; ++i)
{
int del_num = 61 + i;
cout << endl << del_num << endl;
Btree.remove(del_num);
cout << endl;
Btree.inorder_tra(Btree.get_root());
cout << endl;
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b98687a5ae46fef80a9d8cbd13c5e0e1.jpeg)