B-Tree
This commit is contained in:
241
BinaryTree/BalanceTree/B-Tree/B-Tree-By-AI.h
Normal file
241
BinaryTree/BalanceTree/B-Tree/B-Tree-By-AI.h
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Node {
|
||||||
|
bool leaf; // 是否为叶子节点
|
||||||
|
vector<T> keys; // 存储关键字
|
||||||
|
vector<Node*> children; // 孩子节点指针
|
||||||
|
|
||||||
|
Node(bool _leaf) : leaf(_leaf) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class BTree {
|
||||||
|
public:
|
||||||
|
BTree(int _t) : t(_t), root(nullptr) {}
|
||||||
|
|
||||||
|
void insert(const T& key); // 插入关键字
|
||||||
|
void remove(const T& key); // 删除关键字
|
||||||
|
void traverse() { traverse(root); cout << endl; } // 中序遍历
|
||||||
|
|
||||||
|
private:
|
||||||
|
Node<T>* root;
|
||||||
|
int t; // 最小度数
|
||||||
|
|
||||||
|
// ----------- 插入相关辅助函数 -----------
|
||||||
|
void insertNonFull(Node<T>* node, const T& key); // 在非满节点插入
|
||||||
|
void splitChild(Node<T>* parent, int idx); // 分裂子节点
|
||||||
|
|
||||||
|
// ----------- 删除相关辅助函数 -----------
|
||||||
|
void remove(Node<T>* node, const T& key); // 递归删除
|
||||||
|
void removeFromLeaf(Node<T>* node, int idx); // 从叶子节点删除
|
||||||
|
void removeFromNonLeaf(Node<T>* node, int idx); // 从非叶子节点删除
|
||||||
|
T getPredecessor(Node<T>* node, int idx); // 找前驱
|
||||||
|
T getSuccessor(Node<T>* node, int idx); // 找后继
|
||||||
|
void fill(Node<T>* node, int idx); // 保证孩子节点至少 t-1 个关键字
|
||||||
|
void borrowFromPrev(Node<T>* node, int idx); // 从左兄弟借一个关键字
|
||||||
|
void borrowFromNext(Node<T>* node, int idx); // 从右兄弟借一个关键字
|
||||||
|
void merge(Node<T>* node, int idx); // 与右兄弟合并
|
||||||
|
|
||||||
|
// ----------- 遍历辅助函数 -----------
|
||||||
|
void traverse(Node<T>* node);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------- 插入相关 ----------------------
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::insert(const T& key) {
|
||||||
|
if (!root) { // 树空
|
||||||
|
root = new Node<T>(true);
|
||||||
|
root->keys.push_back(key);
|
||||||
|
} else {
|
||||||
|
// 根节点满,先分裂根节点
|
||||||
|
if (root->keys.size() == 2*t - 1) {
|
||||||
|
Node<T>* s = new Node<T>(false);
|
||||||
|
s->children.push_back(root);
|
||||||
|
splitChild(s, 0);
|
||||||
|
root = s;
|
||||||
|
}
|
||||||
|
insertNonFull(root, key); // 插入非满节点
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::insertNonFull(Node<T>* node, const T& key) {
|
||||||
|
int i = node->keys.size() - 1;
|
||||||
|
if (node->leaf) { // 叶子节点直接插入
|
||||||
|
node->keys.push_back(key);
|
||||||
|
while (i >= 0 && node->keys[i] > key) {
|
||||||
|
node->keys[i+1] = node->keys[i];
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
node->keys[i+1] = key;
|
||||||
|
} else { // 内部节点
|
||||||
|
while (i >= 0 && node->keys[i] > key) i--;
|
||||||
|
i++;
|
||||||
|
if (node->children[i]->keys.size() == 2*t-1) {
|
||||||
|
splitChild(node, i); // 分裂满子节点
|
||||||
|
if (node->keys[i] < key) i++;
|
||||||
|
}
|
||||||
|
insertNonFull(node->children[i], key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::splitChild(Node<T>* parent, int idx) {
|
||||||
|
Node<T>* y = parent->children[idx];
|
||||||
|
Node<T>* z = new Node<T>(y->leaf);
|
||||||
|
|
||||||
|
// 把 y 的后 t-1 个关键字移动到 z
|
||||||
|
for (int j = 0; j < t-1; j++) z->keys.push_back(y->keys[j+t]);
|
||||||
|
if (!y->leaf) {
|
||||||
|
for (int j = 0; j < t; j++) z->children.push_back(y->children[j+t]);
|
||||||
|
y->children.resize(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
y->keys.resize(t-1); // 保留前 t-1 个关键字
|
||||||
|
parent->children.insert(parent->children.begin()+idx+1, z);
|
||||||
|
parent->keys.insert(parent->keys.begin()+idx, y->keys[t-1]); // 中间关键字上移
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- 删除相关 ----------------------
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::remove(const T& key) {
|
||||||
|
if (!root) return;
|
||||||
|
remove(root, key);
|
||||||
|
// 如果根节点被删除后没有关键字,调整 root
|
||||||
|
if (root->keys.empty()) {
|
||||||
|
Node<T>* oldRoot = root;
|
||||||
|
if (root->leaf) root = nullptr;
|
||||||
|
else root = root->children[0];
|
||||||
|
delete oldRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::remove(Node<T>* node, const T& key) {
|
||||||
|
int idx = 0;
|
||||||
|
while (idx < node->keys.size() && node->keys[idx] < key) idx++;
|
||||||
|
|
||||||
|
if (idx < node->keys.size() && node->keys[idx] == key) {
|
||||||
|
if (node->leaf) removeFromLeaf(node, idx); // 情况1: 叶子节点直接删除
|
||||||
|
else removeFromNonLeaf(node, idx); // 情况2: 内部节点
|
||||||
|
} else {
|
||||||
|
if (node->leaf) return; // key不存在
|
||||||
|
bool flag = (idx == node->keys.size());
|
||||||
|
// 如果孩子节点关键字不足 t 个,需要调整
|
||||||
|
if (node->children[idx]->keys.size() < t) fill(node, idx);
|
||||||
|
if (flag && idx > node->keys.size()) remove(node->children[idx-1], key);
|
||||||
|
else remove(node->children[idx], key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::removeFromLeaf(Node<T>* node, int idx) {
|
||||||
|
// 叶子节点直接删除关键字
|
||||||
|
node->keys.erase(node->keys.begin() + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::removeFromNonLeaf(Node<T>* node, int idx) {
|
||||||
|
T k = node->keys[idx];
|
||||||
|
// 如果左孩子关键字 >= t,用前驱替换
|
||||||
|
if (node->children[idx]->keys.size() >= t) {
|
||||||
|
T pred = getPredecessor(node, idx);
|
||||||
|
node->keys[idx] = pred;
|
||||||
|
remove(node->children[idx], pred);
|
||||||
|
}
|
||||||
|
// 如果右孩子关键字 >= t,用后继替换
|
||||||
|
else if (node->children[idx+1]->keys.size() >= t) {
|
||||||
|
T succ = getSuccessor(node, idx);
|
||||||
|
node->keys[idx] = succ;
|
||||||
|
remove(node->children[idx+1], succ);
|
||||||
|
}
|
||||||
|
// 左右孩子都不足 t,则合并孩子
|
||||||
|
else {
|
||||||
|
merge(node, idx);
|
||||||
|
remove(node->children[idx], k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T BTree<T>::getPredecessor(Node<T>* node, int idx) {
|
||||||
|
Node<T>* cur = node->children[idx];
|
||||||
|
while (!cur->leaf) cur = cur->children.back();
|
||||||
|
return cur->keys.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T BTree<T>::getSuccessor(Node<T>* node, int idx) {
|
||||||
|
Node<T>* cur = node->children[idx+1];
|
||||||
|
while (!cur->leaf) cur = cur->children[0];
|
||||||
|
return cur->keys[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::fill(Node<T>* node, int idx) {
|
||||||
|
// 尝试从兄弟借关键字,如果不够则合并
|
||||||
|
if (idx != 0 && node->children[idx-1]->keys.size() >= t)
|
||||||
|
borrowFromPrev(node, idx);
|
||||||
|
else if (idx != node->keys.size() && node->children[idx+1]->keys.size() >= t)
|
||||||
|
borrowFromNext(node, idx);
|
||||||
|
else {
|
||||||
|
if (idx != node->keys.size()) merge(node, idx);
|
||||||
|
else merge(node, idx-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::borrowFromPrev(Node<T>* node, int idx) {
|
||||||
|
Node<T>* child = node->children[idx];
|
||||||
|
Node<T>* sibling = node->children[idx-1];
|
||||||
|
|
||||||
|
// 将父节点关键字下移到 child 前面
|
||||||
|
child->keys.insert(child->keys.begin(), node->keys[idx-1]);
|
||||||
|
if (!child->leaf) child->children.insert(child->children.begin(), sibling->children.back());
|
||||||
|
node->keys[idx-1] = sibling->keys.back();
|
||||||
|
sibling->keys.pop_back();
|
||||||
|
if (!sibling->leaf) sibling->children.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::borrowFromNext(Node<T>* node, int idx) {
|
||||||
|
Node<T>* child = node->children[idx];
|
||||||
|
Node<T>* sibling = node->children[idx+1];
|
||||||
|
|
||||||
|
// 将父节点关键字下移到 child 后面
|
||||||
|
child->keys.push_back(node->keys[idx]);
|
||||||
|
if (!child->leaf) child->children.push_back(sibling->children[0]);
|
||||||
|
node->keys[idx] = sibling->keys[0];
|
||||||
|
sibling->keys.erase(sibling->keys.begin());
|
||||||
|
if (!sibling->leaf) sibling->children.erase(sibling->children.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::merge(Node<T>* node, int idx) {
|
||||||
|
Node<T>* child = node->children[idx];
|
||||||
|
Node<T>* sibling = node->children[idx+1];
|
||||||
|
|
||||||
|
// 将父节点关键字和 sibling 的关键字都移入 child
|
||||||
|
child->keys.push_back(node->keys[idx]);
|
||||||
|
child->keys.insert(child->keys.end(), sibling->keys.begin(), sibling->keys.end());
|
||||||
|
if (!child->leaf) child->children.insert(child->children.end(), sibling->children.begin(), sibling->children.end());
|
||||||
|
|
||||||
|
// 删除父节点中的关键字和 sibling 指针
|
||||||
|
node->keys.erase(node->keys.begin() + idx);
|
||||||
|
node->children.erase(node->children.begin() + idx + 1);
|
||||||
|
delete sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- 遍历 ----------------------
|
||||||
|
template<class T>
|
||||||
|
void BTree<T>::traverse(Node<T>* node) {
|
||||||
|
if (!node) return;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < node->keys.size(); i++) {
|
||||||
|
if (!node->leaf) traverse(node->children[i]);
|
||||||
|
cout << node->keys[i] << " ";
|
||||||
|
}
|
||||||
|
if (!node->leaf) traverse(node->children[i]);
|
||||||
|
}
|
@@ -131,5 +131,169 @@ inline bool BTree<T>::search(Node<T>* _node, const T& _key)
|
|||||||
template<class T>
|
template<class T>
|
||||||
inline void BTree<T>::erase(const T& _key)
|
inline void BTree<T>::erase(const T& _key)
|
||||||
{
|
{
|
||||||
//1-ɾ<><C9BE>Ҷ<EFBFBD><EFBFBD>
|
if (!root) return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><>һ<EFBFBD><D2BB><EFBFBD>ݹ<EFBFBD> lambda <20><>ʵ<EFBFBD><CAB5>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>
|
||||||
|
auto remove = [&](auto&& self, Node<T>* node, const T& key) -> void {
|
||||||
|
int idx = 0;
|
||||||
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD>һ<EFBFBD><D2BB> >= key <20><>λ<EFBFBD><CEBB>
|
||||||
|
while (idx < node->keys.size() && node->keys[idx] < key) idx++;
|
||||||
|
|
||||||
|
// ==============================================================
|
||||||
|
// <20><><EFBFBD><EFBFBD> 1<><31>key <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD> node->keys[idx]
|
||||||
|
// ==============================================================
|
||||||
|
if (idx < node->keys.size() && node->keys[idx] == key) {
|
||||||
|
// ---- 1.1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Ҷ<EFBFBD>ӣ<EFBFBD>ֱ<EFBFBD><D6B1>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (node->isLeaf) {
|
||||||
|
node->keys.erase(node->keys.begin() + idx);
|
||||||
|
}
|
||||||
|
// ---- 1.2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2>ڵ㣨<DAB5><E3A3A8>Ҷ<EFBFBD>ӣ<EFBFBD>
|
||||||
|
else {
|
||||||
|
Node<T>* leftChild = node->children[idx];
|
||||||
|
Node<T>* rightChild = node->children[idx + 1];
|
||||||
|
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t <20><><EFBFBD>ؼ<EFBFBD><D8BC>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||||
|
if (leftChild->keys.size() >= t) {
|
||||||
|
// <20>ҵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ<EFBFBD>Ԫ<EFBFBD>أ<EFBFBD>
|
||||||
|
Node<T>* cur = leftChild;
|
||||||
|
while (!cur->isLeaf) cur = cur->children.back();
|
||||||
|
T pred = cur->keys.back();
|
||||||
|
// <20><>ǰ<EFBFBD><C7B0><EFBFBD>滻<EFBFBD><E6BBBB>ǰ key
|
||||||
|
node->keys[idx] = pred;
|
||||||
|
// <20>ݹ<EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>ǰ<EFBFBD><C7B0>
|
||||||
|
self(self, leftChild, pred);
|
||||||
|
}
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t <20><><EFBFBD>ؼ<EFBFBD><D8BC>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||||
|
else if (rightChild->keys.size() >= t) {
|
||||||
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>أ<EFBFBD>
|
||||||
|
Node<T>* cur = rightChild;
|
||||||
|
while (!cur->isLeaf) cur = cur->children.front();
|
||||||
|
T succ = cur->keys.front();
|
||||||
|
// <20>ú<EFBFBD><C3BA><EFBFBD><EFBFBD>滻<EFBFBD><E6BBBB>ǰ key
|
||||||
|
node->keys[idx] = succ;
|
||||||
|
// <20>ݹ<EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
self(self, rightChild, succ);
|
||||||
|
}
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB> t-1 <20><><EFBFBD>ؼ<EFBFBD><D8BC>֣<EFBFBD><D6A3><EFBFBD><DEB7><EFBFBD> <20><> <20>ϲ<EFBFBD>
|
||||||
|
else {
|
||||||
|
// <20><> key <20>³<EFBFBD><C2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
leftChild->keys.push_back(node->keys[idx]);
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> keys ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
leftChild->keys.insert(leftChild->keys.end(),
|
||||||
|
rightChild->keys.begin(), rightChild->keys.end());
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> children <20><><EFBFBD><EFBFBD>ȥ
|
||||||
|
if (!leftChild->isLeaf) {
|
||||||
|
leftChild->children.insert(leftChild->children.end(),
|
||||||
|
rightChild->children.begin(), rightChild->children.end());
|
||||||
|
}
|
||||||
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>е<EFBFBD> key <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||||
|
node->keys.erase(node->keys.begin() + idx);
|
||||||
|
node->children.erase(node->children.begin() + idx + 1);
|
||||||
|
delete rightChild;
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ںϲ<DABA><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE> key
|
||||||
|
self(self, leftChild, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ==============================================================
|
||||||
|
// <20><><EFBFBD><EFBFBD> 2<><32>key <20><><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD> <20><> ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// ==============================================================
|
||||||
|
else {
|
||||||
|
if (node->isLeaf) return; // <20><>Ҷ<EFBFBD>ӻ<EFBFBD>û<EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>У<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>
|
||||||
|
|
||||||
|
bool flag = (idx == node->keys.size()); // key <20><><EFBFBD><EFBFBD><EFBFBD>нڵ㶼<DAB5><E3B6BC> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
Node<T>* child = node->children[idx];
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// ɾ<><C9BE>֮ǰҪ<C7B0><D2AA>֤ child <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t <20><><EFBFBD>ؼ<EFBFBD><D8BC>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD>겻<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
if (child->keys.size() < t) {
|
||||||
|
Node<T>* leftSibling = (idx > 0 ? node->children[idx - 1] : nullptr);
|
||||||
|
Node<T>* rightSibling = (idx < node->keys.size() ? node->children[idx + 1] : nullptr);
|
||||||
|
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵܴ<D6B5><DCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> >= t <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ֵܽ<D6B5>
|
||||||
|
if (leftSibling && leftSibling->keys.size() >= t) {
|
||||||
|
// <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> key <20><> child
|
||||||
|
child->keys.insert(child->keys.begin(), node->keys[idx - 1]);
|
||||||
|
// <20><><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> key <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
|
node->keys[idx - 1] = leftSibling->keys.back();
|
||||||
|
leftSibling->keys.pop_back();
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD> children
|
||||||
|
if (!leftSibling->isLeaf) {
|
||||||
|
child->children.insert(child->children.begin(), leftSibling->children.back());
|
||||||
|
leftSibling->children.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵܴ<D6B5><DCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> >= t <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ֵܽ<D6B5>
|
||||||
|
else if (rightSibling && rightSibling->keys.size() >= t) {
|
||||||
|
// <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> key <20><> child
|
||||||
|
child->keys.push_back(node->keys[idx]);
|
||||||
|
// <20><><EFBFBD>ֵܵ<D6B5>һ<EFBFBD><D2BB> key <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
||||||
|
node->keys[idx] = rightSibling->keys.front();
|
||||||
|
rightSibling->keys.erase(rightSibling->keys.begin());
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD> children
|
||||||
|
if (!rightSibling->isLeaf) {
|
||||||
|
child->children.push_back(rightSibling->children.front());
|
||||||
|
rightSibling->children.erase(rightSibling->children.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ֵܶ<D6B5><DCB6><EFBFBD><EFBFBD><EFBFBD> t <20><> <20>ϲ<EFBFBD>
|
||||||
|
else {
|
||||||
|
if (leftSibling) {
|
||||||
|
// <20>Ѹ<EFBFBD><D1B8>ڵ<EFBFBD>һ<EFBFBD><D2BB> key <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ֵ<EFBFBD>
|
||||||
|
leftSibling->keys.push_back(node->keys[idx - 1]);
|
||||||
|
// <20><> child <20><> keys ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
|
||||||
|
leftSibling->keys.insert(leftSibling->keys.end(),
|
||||||
|
child->keys.begin(), child->keys.end());
|
||||||
|
if (!child->isLeaf) {
|
||||||
|
leftSibling->children.insert(leftSibling->children.end(),
|
||||||
|
child->children.begin(), child->children.end());
|
||||||
|
}
|
||||||
|
// <20><><EFBFBD>ڵ<EFBFBD>ɾ<EFBFBD><C9BE> key <20><> child ָ<><D6B8>
|
||||||
|
node->keys.erase(node->keys.begin() + idx - 1);
|
||||||
|
node->children.erase(node->children.begin() + idx);
|
||||||
|
delete child;
|
||||||
|
child = leftSibling;
|
||||||
|
}
|
||||||
|
else if (rightSibling) {
|
||||||
|
// <20>Ѹ<EFBFBD><D1B8>ڵ<EFBFBD>һ<EFBFBD><D2BB> key <20><><EFBFBD>Ƶ<EFBFBD> child
|
||||||
|
child->keys.push_back(node->keys[idx]);
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ֵܵ<D6B5> keys ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> child
|
||||||
|
child->keys.insert(child->keys.end(),
|
||||||
|
rightSibling->keys.begin(), rightSibling->keys.end());
|
||||||
|
if (!rightSibling->isLeaf) {
|
||||||
|
child->children.insert(child->children.end(),
|
||||||
|
rightSibling->children.begin(), rightSibling->children.end());
|
||||||
|
}
|
||||||
|
node->keys.erase(node->keys.begin() + idx);
|
||||||
|
node->children.erase(node->children.begin() + idx + 1);
|
||||||
|
delete rightSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// <20><>֤ child <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t <20><> key <20>ݹ<F3A3ACB5><DDB9><EFBFBD>ȥ
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
if (flag && idx > node->keys.size())
|
||||||
|
self(self, node->children[idx - 1], key);
|
||||||
|
else
|
||||||
|
self(self, node->children[idx], key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>
|
||||||
|
remove(remove, root, _key);
|
||||||
|
|
||||||
|
// ==============================================================
|
||||||
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5>¸<EFBFBD><C2B8>ڵ<EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||||
|
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> root û<><C3BB> key <20><>
|
||||||
|
// ==============================================================
|
||||||
|
if (root->keys.empty()) {
|
||||||
|
Node<T>* oldRoot = root;
|
||||||
|
// <20><><EFBFBD><EFBFBD> root <20><>Ҷ<EFBFBD><D2B6> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||||
|
if (root->isLeaf) root = nullptr;
|
||||||
|
else root = root->children[0]; // root <20><>Ψһ<CEA8><D2BB><EFBFBD>ӳ<EFBFBD>Ϊ<EFBFBD>µĸ<C2B5>
|
||||||
|
delete oldRoot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,10 @@ int main() {
|
|||||||
a.insert(11);a.display();
|
a.insert(11);a.display();
|
||||||
a.insert(15);a.display();
|
a.insert(15);a.display();
|
||||||
a.insert(17);a.display();
|
a.insert(17);a.display();
|
||||||
|
|
||||||
|
a.erase(7);a.display();
|
||||||
|
a.erase(10);a.display();
|
||||||
|
a.erase(1);a.display();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -70,4 +74,28 @@ int main() {
|
|||||||
6 7 8
|
6 7 8
|
||||||
9 10
|
9 10
|
||||||
11 15 17
|
11 15 17
|
||||||
|
|
||||||
|
|
||||||
|
1 2
|
||||||
|
3 4 5
|
||||||
|
|
||||||
|
6 8
|
||||||
|
9 10
|
||||||
|
11 15 17
|
||||||
|
|
||||||
|
|
||||||
|
1 2
|
||||||
|
3 4 5
|
||||||
|
|
||||||
|
6 8
|
||||||
|
9 11
|
||||||
|
15 17
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
3 4 5
|
||||||
|
6 8
|
||||||
|
|
||||||
|
9 11
|
||||||
|
15 17
|
||||||
*/
|
*/
|
Reference in New Issue
Block a user