This commit is contained in:
e2hang
2025-08-26 19:13:51 +08:00
parent 74b56aa55c
commit fe9d51456b
4 changed files with 793 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
#pragma once
#include <iostream>
#include "Node.h"
#include <algorithm>
template <class T>
class BTree {
private:
Node<T>* root;
int t; //*B-<2D><><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>ڵ<EFBFBD><DAB5>϶<EFBFBD><CFB6><EFBFBD>t - 1 <20><> 2t - 1
void splitChild(Node<T>* _node, int _n);
void insertNonFull(Node<T>* _node, const T& _key);
void inorder(Node<T>* _n) {
if (!_n) return;
int i = 0;
//<2F><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>inorder(children[0]) -> inorder(key[0]) -> inorder(children[1])... <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>
for (i = 0; i < _n->keys.size(); i++) {
if (i < _n->children.size()) inorder(_n->children[i]);
std::cout << _n->keys[i] << " ";
}
//<2F>Ѿ<EFBFBD>i++
if (i < _n->children.size()) inorder(_n->children[i]);
std::cout << std::endl;
}
public:
BTree() = delete;
BTree(int _t) : t(_t), root(nullptr) {}
void display() { inorder(root); }
void insert(const T& _key);
bool search(Node<T>* _node, const T& _key);
void erase(const T& _key);
};
template<class T>
inline void BTree<T>::splitChild(Node<T>* _pt, int _i)
{
//_pt-<2D><><EFBFBD>ڵ<EFBFBD>//_i-<2D>ڼ<EFBFBD><DABC><EFBFBD><EFBFBD>ӽڵ<D3BD>//t-<2D>м<EFBFBD>Ԫ<EFBFBD><D4AA>
Node<T>* p = _pt->children[_i];
Node<T>* tmp = new Node<T>(p->isLeaf);
int mid = t - 1;
//<2F><><EFBFBD><EFBFBD>mid<69>Ҳ<EFBFBD>
for (int i = 0; i < mid; i++) {
tmp->keys.push_back(p->keys[t + i]);
}
//<2F><><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽڵ<D3BD>-<2D><><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD>
if (!p->isLeaf) {
for (int i = 0; i < t; i++) {
tmp->children.push_back(p->children[i + t]);
}
}
T middlekey = p->keys[mid];
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
p->keys.resize(mid);
if (!p->isLeaf) p->children.resize(t);//t = mid + 1
//<2F><><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD>
_pt->children.insert(_pt->children.begin() + _i + 1, tmp);
//<2F><>ȡ<EFBFBD>м<EFBFBD>Ԫ<EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_pt->keys.insert(_pt->keys.begin() + _i, middlekey);
}
template<class T>
inline void BTree<T>::insertNonFull(Node<T>* _node, const T& _key)
{
int i = _node->keys.size() - 1;
//<2F><>Ҷ<EFBFBD>ӽڵ<D3BD>-<2D>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(n)
if (_node->isLeaf) {
_node->keys.push_back(_key);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
while (i >= 0 && _node->keys[i] > _key) {
_node->keys[i + 1] = _node->keys[i];
i--;
}
_node->keys[i + 1] = _key;
}
//<2F><><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽڵ㣬<DAB5>ݹ<EFBFBD><DDB9><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0>Ҷ<EFBFBD>ӽڵ<D3BD>
else {
while (i >= 0 && _node->keys[i] > _key) {
i--;
}
i++;//<2F>ҵ<EFBFBD>childrenλ<6E><CEBB>
//<2F>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
if (_node->children[i]->keys.size() == 2 * t - 1) {
splitChild(_node, i);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܸı<DCB8><C4B1>ؼ<EFBFBD><D8BC><EFBFBD>λ<EFBFBD><CEBB>
if (_key > _node->keys[i]) i++;
}
insertNonFull(_node->children[i], _key);
}
}
template<class T>
inline void BTree<T>::insert(const T& _key)
{
//1-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>root
if (!root) {
root = new Node<T>(true);
root->keys.push_back(_key);
}
//2-<2D><>root<6F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else {
//root<6F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѹ<EFBFBD><D1B8>ڵ<EFBFBD>
//<2F>ص<EFBFBD><D8B5><EFBFBD>ע:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>򣬲<EFBFBD><F2A3ACB2>ܹؼ<DCB9><D8BC><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>һ
if (root->keys.size() == 2*t - 1) {
Node<T>* _root = new Node<T>(false);
_root->children.push_back(root);
splitChild(_root, 0);
root = _root;
}
//<2F><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>
insertNonFull(root, _key);
}
//<2F><> t = 2<><32>root Ŀǰ<C4BF><C7B0> 2 <20><>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ԫ<EFBFBD>غ<EFBFBD><D8BA><EFBFBD>root <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3 <20><>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD>ڵ㣩<DAB5><E3A3A9><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѣ<EFBFBD><D1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߼<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EBB3AC> 3 <20><>Ԫ<EFBFBD><D4AA>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
template<class T>
inline bool BTree<T>::search(Node<T>* _node, const T& _key)
{
//<2F><><EFBFBD>Եݹ<D4B5><DDB9><EFBFBD>
Node<T>* tmp = _node;
int i = 0;
while (tmp->keys[i] < _key && i < tmp->keys.size()) i++;
if (tmp->keys[i] == _key) return true;
if(tmp->isLeaf) return false;
return search(_node->children[i], _key);
}
template<class T>
inline void BTree<T>::erase(const T& _key)
{
//1-ɾ<><C9BE>Ҷ<EFBFBD><D2B6>
}