Balance Tree
This commit is contained in:
		
							
								
								
									
										378
									
								
								BinaryTree/BalanceTree/BPlus-Tree/BPlusTree.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								BinaryTree/BalanceTree/BPlus-Tree/BPlusTree.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,378 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Node.h"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
class BPlusTree {
 | 
			
		||||
private:
 | 
			
		||||
	Node<T>* root;
 | 
			
		||||
	int M;
 | 
			
		||||
	Node<T>* firstLeaf;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD>
 | 
			
		||||
 | 
			
		||||
	void splitChild(Node<T>* _node, int _i);
 | 
			
		||||
	void insertNonFull(Node<T>* _node, const T& _key);
 | 
			
		||||
	void erase(Node<T>* _node, const T& _key);
 | 
			
		||||
	//void fixUnderflow(Node<T>* _node);ûд parent
 | 
			
		||||
	T& getMin(Node<T>* _node);
 | 
			
		||||
 | 
			
		||||
	void borrowLeft(Node<T>* _node, int _i);
 | 
			
		||||
	void borrowRight(Node<T>* _node, int _i);
 | 
			
		||||
	void mergeLeft(Node<T>* _node, int _i);
 | 
			
		||||
	void mergeRight(Node<T>* _node, int _i);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	BPlusTree() = delete;
 | 
			
		||||
	BPlusTree(int _M) : M(_M) {
 | 
			
		||||
		root = new Node<T>(true);
 | 
			
		||||
		firstLeaf = root;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void insert(const T& _key);
 | 
			
		||||
	Node<T>* search(const T& _key);
 | 
			
		||||
	void areaSearch(const T& _low, const T& _up);
 | 
			
		||||
	void displayLeaf();
 | 
			
		||||
	void erase(const T& _key);
 | 
			
		||||
	
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::splitChild(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	Node<T>* child = _node->children[_i];
 | 
			
		||||
	Node<T>* newc = new Node<T>(_node->children[_i]->isLeaf);
 | 
			
		||||
	//<2F>е㣬<D0B5><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>㷽ʽ<E3B7BD>ˣ<EFBFBD>֮ǰ<D6AE><C7B0>t - 1 <20><> 2t - 1
 | 
			
		||||
	int mid = (M - 1) / 2;
 | 
			
		||||
	//midǰ<64><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mid<69><64>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
 | 
			
		||||
	newc->keys.assign(child->keys.begin() + mid, child->keys.end());
 | 
			
		||||
	child->keys.resize(mid);
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	if (!child->isLeaf) {
 | 
			
		||||
		newc->children.assign(child->children.begin() + mid + 1, child->children.end());
 | 
			
		||||
		child->children.resize(mid + 1);
 | 
			
		||||
	}
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD>next<78>ڵ<EFBFBD>
 | 
			
		||||
	if (child->isLeaf) {
 | 
			
		||||
		newc->next = child->next;
 | 
			
		||||
		child->next = newc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//<2F><>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>-<2D><><EFBFBD><EFBFBD>_node<64><65>һ<EFBFBD>㶼<EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ<D0A1><D6B5>
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2>ⲿ<EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
	if (!child->isLeaf) 
 | 
			
		||||
		//ɾ<><C9BE>newc<77><63>һ<EFBFBD><D2BB>:<3A><><EFBFBD><EFBFBD>-1,2,3,4,5<><35><EFBFBD><EFBFBD>Ϊ1,2;3,4,5<><35><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>3<EFBFBD><33>Ҫ<EFBFBD><D2AA>3<EFBFBD><33>newc<77>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ƴ<EFBFBD>
 | 
			
		||||
		newc->keys.erase(newc->keys.begin());
 | 
			
		||||
 | 
			
		||||
	_node->keys.insert(_node->keys.begin() + _i, newc->keys.front());
 | 
			
		||||
	_node->children.insert(_node->children.begin() + _i + 1, newc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::insertNonFull(Node<T>* _node, const T& _key)
 | 
			
		||||
{
 | 
			
		||||
	//<2F><>Ҷ<EFBFBD>ӽڵ<D3BD>ֱ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>
 | 
			
		||||
	if (_node->isLeaf) {
 | 
			
		||||
		auto it = std::lower_bound(_node->keys.begin(), _node->keys.end(), _key);
 | 
			
		||||
		_node->keys.insert(it, _key); // <20><><EFBFBD>뵽<EFBFBD><EBB5BD>һ<EFBFBD><D2BB> >= _key <20><>λ<EFBFBD><CEBB>
 | 
			
		||||
	}
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD>ŵݹ<C5B5>Ѱ<EFBFBD><D1B0>
 | 
			
		||||
	else {
 | 
			
		||||
		auto it = std::lower_bound(_node->keys.begin(), _node->keys.end(), _key);
 | 
			
		||||
		int idx = it - _node->keys.begin();
 | 
			
		||||
		if (_node->children[idx]->keys.size() == M - 1) {
 | 
			
		||||
			splitChild(_node, idx);
 | 
			
		||||
		}
 | 
			
		||||
		//<2F><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>
 | 
			
		||||
		if (_node->keys[idx] < _key) idx++;
 | 
			
		||||
		insertNonFull(_node->children[idx], _key);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::erase(Node<T>* _node, const T& _key)
 | 
			
		||||
{
 | 
			
		||||
	int mid = (M - 1) / 2;
 | 
			
		||||
	if (!search(_key)) return;
 | 
			
		||||
	if (!_node) return;
 | 
			
		||||
	//ǰһ<C7B0><D2BB><EFBFBD><EFBFBD>searchһ<68><D2BB>
 | 
			
		||||
	//<2F>ⲿ<EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
	if (_node->isLeaf) {
 | 
			
		||||
		auto it = std::lower_bound(_node->keys.begin(), _node->keys.end(), _key);
 | 
			
		||||
		int idx = it - _node->keys.begin();
 | 
			
		||||
		if(it != _node->keys.end() && *it == _key)
 | 
			
		||||
			_node->keys.erase(it);
 | 
			
		||||
		//û<><C3BB>ֱ<EFBFBD><D6B1>return
 | 
			
		||||
		if (root == _node || _node->keys.size() >= mid){
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//<2F>ڲ<EFBFBD><DAB2>ڵ<EFBFBD>
 | 
			
		||||
	else {
 | 
			
		||||
		auto it = std::lower_bound(_node->keys.begin(), _node->keys.end(), _key);
 | 
			
		||||
		int idx = it - _node->keys.begin();
 | 
			
		||||
		//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻<EFBFBD><E6BBBB>ֵΪchildren[idx]<5D>ĵڶ<C4B5>Сֵ
 | 
			
		||||
		if (it != _node->keys.end() && *it == _key) {
 | 
			
		||||
			*it = getMin(_node->children[idx + 1]);
 | 
			
		||||
		}
 | 
			
		||||
		erase(_node->children[idx], _key);
 | 
			
		||||
 | 
			
		||||
		//<2F><><EFBFBD>ݵ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>磬<EFBFBD><E7A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>飨<EFBFBD><E9A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>parent<6E>ڵ<EFBFBD><DAB5><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>fixunderflow(_node)<29>ˣ<EFBFBD>
 | 
			
		||||
		Node<T>* child = _node->children[idx];
 | 
			
		||||
 | 
			
		||||
		if (child->keys.size() < mid) {
 | 
			
		||||
			//<2F>Ƚ<EFBFBD>
 | 
			
		||||
			// <20><><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
			if (idx > 0 && _node->children[idx - 1]->keys.size() > mid) {
 | 
			
		||||
				borrowLeft(_node, idx);
 | 
			
		||||
			}
 | 
			
		||||
			// <20><><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
			else if (idx < _node->children.size() - 1 && _node->children[idx + 1]->keys.size() > mid) {
 | 
			
		||||
				borrowRight(_node, idx);
 | 
			
		||||
			}
 | 
			
		||||
			// <20>費<EFBFBD><E8B2BB><EFBFBD>ͺϲ<CDBA>
 | 
			
		||||
			else if (idx > 0) {
 | 
			
		||||
				mergeLeft(_node, idx);  // <20><><EFBFBD><EFBFBD><EFBFBD>ֵܺϲ<DCBA>
 | 
			
		||||
			}
 | 
			
		||||
			else if (idx < _node->children.size() - 1) {
 | 
			
		||||
				mergeRight(_node, idx); // <20><><EFBFBD><EFBFBD><EFBFBD>ֵܺϲ<DCBA>
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::fixUnderflow(Node<T>* _node)
 | 
			
		||||
{
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD><EFBFBD>Ա߽<D4B1>
 | 
			
		||||
	
 | 
			
		||||
	//<2F>費<EFBFBD><E8B2BB><EFBFBD>ͺϲ<CDBA>
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline T& BPlusTree<T>::getMin(Node<T>* _node)
 | 
			
		||||
{
 | 
			
		||||
	if (!_node || _node->keys.empty()) {
 | 
			
		||||
		throw std::runtime_error("Empty node has no minimum key");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Node<T>* cur = _node;
 | 
			
		||||
	while (!cur->isLeaf) {
 | 
			
		||||
		cur = cur->children[0];  // <20>ص<EFBFBD>:<3A><>С<EFBFBD>ģ<EFBFBD>һֱ<D2BB><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	}
 | 
			
		||||
	return cur->keys[0];        // <20><><EFBFBD><EFBFBD>Ҷ<EFBFBD>ӵĵ<D3B5>һ<EFBFBD><D2BB> key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::borrowLeft(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	// Ҷ<>ӽڵ<D3BD>
 | 
			
		||||
	if (_node->isLeaf) {
 | 
			
		||||
		T tmp = _node->children[_i - 1]->keys.back();
 | 
			
		||||
		_node->children[_i - 1]->keys.pop_back();
 | 
			
		||||
		_node->children[_i]->keys.insert(_node->children[_i]->keys.begin(), tmp);
 | 
			
		||||
		_node->keys[_i - 1] = _node->children[_i]->keys[0]; // <20><><EFBFBD>¸<EFBFBD><C2B8>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key
 | 
			
		||||
	}
 | 
			
		||||
	// <20>ڲ<EFBFBD><DAB2>ڵ<EFBFBD>
 | 
			
		||||
	else {
 | 
			
		||||
		Node<T>* left = _node->children[_i - 1];
 | 
			
		||||
		Node<T>* cur = _node->children[_i];
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key <20>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>
 | 
			
		||||
		cur->keys.insert(cur->keys.begin(), _node->keys[_i - 1]);
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD> key <20>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
		_node->keys[_i - 1] = left->keys.back();
 | 
			
		||||
		left->keys.pop_back();
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5>ף<EFBFBD><D7A3><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD>һ<EFBFBD><EFBFBD>
 | 
			
		||||
		Node<T>* c = left->children.back();
 | 
			
		||||
		left->children.pop_back();
 | 
			
		||||
		cur->children.insert(cur->children.begin(), c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::borrowRight(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	// Ҷ<>ӽڵ<D3BD>
 | 
			
		||||
	if (_node->isLeaf) {
 | 
			
		||||
		Node<T>* cur = _node->children[_i];
 | 
			
		||||
		Node<T>* right = _node->children[_i + 1];
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ֵܵ<D6B5>һ<EFBFBD><D2BB> key <20>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>ĩβ
 | 
			
		||||
		T tmp = right->keys.front();
 | 
			
		||||
		right->keys.erase(right->keys.begin());
 | 
			
		||||
		cur->keys.push_back(tmp);
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>¸<EFBFBD><C2B8>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key
 | 
			
		||||
		_node->keys[_i] = right->keys.front();
 | 
			
		||||
	}
 | 
			
		||||
	// <20>ڲ<EFBFBD><DAB2>ڵ<EFBFBD>
 | 
			
		||||
	else {
 | 
			
		||||
		Node<T>* cur = _node->children[_i];
 | 
			
		||||
		Node<T>* right = _node->children[_i + 1];
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key <20>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>ĩβ
 | 
			
		||||
		cur->keys.push_back(_node->keys[_i]);
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ֵܵ<D6B5>һ<EFBFBD><D2BB> key <20>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
		_node->keys[_i] = right->keys.front();
 | 
			
		||||
		right->keys.erase(right->keys.begin());
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD>ֵܵ<D6B5>һ<EFBFBD><D2BB><EFBFBD>ӽڵ<D3BD><DAB5>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>ĩβ
 | 
			
		||||
		Node<T>* c = right->children.front();
 | 
			
		||||
		right->children.erase(right->children.begin());
 | 
			
		||||
		cur->children.push_back(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::mergeLeft(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
 | 
			
		||||
	Node<T>* c = _node->children[_i];
 | 
			
		||||
	_node->keys.erase(_node->keys.begin() + _i);
 | 
			
		||||
	//<2F>ϲ<EFBFBD>
 | 
			
		||||
	_node->children[_i - 1].insert(_node->children[_i - 1].end(), c.begin(), c.end());
 | 
			
		||||
	_node->children[_i - 1]->children.insert(_node->children[_i - 1]->children.end(), c->children.begin(), c->children.end());
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::mergeLeft(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	Node<T>* left = _node->children[_i - 1];
 | 
			
		||||
	Node<T>* cur = _node->children[_i];
 | 
			
		||||
 | 
			
		||||
	// 1. <20><><EFBFBD>ڵ<EFBFBD> key <20>ƶ<EFBFBD> / ɾ<><C9BE>
 | 
			
		||||
	if (!left->isLeaf) {
 | 
			
		||||
		// <20>ڲ<EFBFBD><DAB2>ڵ㣺<DAB5><E3A3BA><EFBFBD>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key <20>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ֵ<EFBFBD>ĩβ
 | 
			
		||||
		left->keys.push_back(_node->keys[_i - 1]);
 | 
			
		||||
	}
 | 
			
		||||
	_node->keys.erase(_node->keys.begin() + (_i - 1));
 | 
			
		||||
 | 
			
		||||
	// 2. <20>ϲ<EFBFBD> keys
 | 
			
		||||
	left->keys.insert(left->keys.end(), cur->keys.begin(), cur->keys.end());
 | 
			
		||||
 | 
			
		||||
	// 3. <20>ϲ<EFBFBD> children<65><6E><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2>ڵ㣩
 | 
			
		||||
	if (!left->isLeaf) {
 | 
			
		||||
		left->children.insert(left->children.end(), cur->children.begin(), cur->children.end());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 4. Ҷ<>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD> next ָ<><D6B8>
 | 
			
		||||
	if (left->isLeaf) {
 | 
			
		||||
		left->next = cur->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 5. ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD> children <20>еĵ<D0B5>ǰ<EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
	_node->children.erase(_node->children.begin() + _i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::mergeRight(Node<T>* _node, int _i)
 | 
			
		||||
{
 | 
			
		||||
	Node<T>* cur = _node->children[_i];
 | 
			
		||||
	Node<T>* right = _node->children[_i + 1];
 | 
			
		||||
 | 
			
		||||
	// 1. <20><><EFBFBD>ڵ<EFBFBD> key
 | 
			
		||||
	if (!cur->isLeaf) {
 | 
			
		||||
		// <20>ڲ<EFBFBD><DAB2>ڵ㣺<DAB5><E3A3BA><EFBFBD>ڵ<EFBFBD><DAB5>ֽ<EFBFBD> key <20>Ƶ<EFBFBD><C6B5><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>ĩβ
 | 
			
		||||
		cur->keys.push_back(_node->keys[_i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 2. <20>ϲ<EFBFBD> keys
 | 
			
		||||
	cur->keys.insert(cur->keys.end(), right->keys.begin(), right->keys.end());
 | 
			
		||||
 | 
			
		||||
	// 3. <20>ϲ<EFBFBD> children<65><6E><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2>ڵ㣩
 | 
			
		||||
	if (!cur->isLeaf) {
 | 
			
		||||
		cur->children.insert(cur->children.end(), right->children.begin(), right->children.end());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 4. Ҷ<>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD> next ָ<><D6B8>
 | 
			
		||||
	if (cur->isLeaf) {
 | 
			
		||||
		cur->next = right->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 5. ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD> key
 | 
			
		||||
	_node->keys.erase(_node->keys.begin() + _i);
 | 
			
		||||
 | 
			
		||||
	// 6. ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD> children <20>е<EFBFBD><D0B5><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
	_node->children.erase(_node->children.begin() + _i + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::insert(const T& _key)
 | 
			
		||||
{
 | 
			
		||||
	//<2F><><EFBFBD>Ѹ<EFBFBD>
 | 
			
		||||
	if (root->keys.size() == M - 1) {
 | 
			
		||||
		Node<T>* newr = new Node<T>(false);
 | 
			
		||||
		newr->children.push_back(root);
 | 
			
		||||
		splitChild(newr, 0);
 | 
			
		||||
		root = newr;
 | 
			
		||||
	}
 | 
			
		||||
	//<2F><><EFBFBD><EFBFBD>
 | 
			
		||||
	insertNonFull(root, _key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline Node<T>* BPlusTree<T>::search(const T& _key)
 | 
			
		||||
{
 | 
			
		||||
	Node<T>* tmp = root;
 | 
			
		||||
	while (tmp) {
 | 
			
		||||
		auto it = std::lower_bound(tmp->keys.begin(), tmp->keys.end(), _key);
 | 
			
		||||
		int idx = it - tmp->keys.begin();
 | 
			
		||||
 | 
			
		||||
		if (tmp->isLeaf) {
 | 
			
		||||
			//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>tmp<6D><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ٸ<EFBFBD><D9B8>ݷ<EFBFBD><DDB7>ص<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>һ<EFBFBD>鼴<EFBFBD><E9BCB4>
 | 
			
		||||
			return tmp;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			tmp = tmp->children[idx];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::areaSearch(const T& _low, const T& _up)
 | 
			
		||||
{
 | 
			
		||||
	//<2F><><EFBFBD>ò<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>search<63><68><EFBFBD><EFBFBD><EFBFBD>صĶ<D8B5><C4B6><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
 | 
			
		||||
	Node<T>* tmp = search(_low);
 | 
			
		||||
	if (!tmp) return;
 | 
			
		||||
	while (tmp) {
 | 
			
		||||
		for (auto x : tmp->keys) {
 | 
			
		||||
			if (x > _up) {
 | 
			
		||||
				std::cout << std::endl;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (x >= _low) std::cout << x << " ";
 | 
			
		||||
		}
 | 
			
		||||
		tmp = tmp->next;
 | 
			
		||||
	}
 | 
			
		||||
	std::cout << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::displayLeaf()
 | 
			
		||||
{
 | 
			
		||||
	Node<T>* tmp = firstLeaf;
 | 
			
		||||
	while (tmp) {
 | 
			
		||||
		for (auto x : tmp->keys) std::cout << x << " ";
 | 
			
		||||
		tmp = tmp->next;
 | 
			
		||||
		std::cout << "C ";
 | 
			
		||||
	}
 | 
			
		||||
	std::cout << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void BPlusTree<T>::erase(const T& _key)
 | 
			
		||||
{
 | 
			
		||||
	if (!root) return;
 | 
			
		||||
	//<2F>ݹ<EFBFBD>ɾ<EFBFBD><C9BE>
 | 
			
		||||
	erase(root, _key);
 | 
			
		||||
	if (root->isLeaf && root->keys.size() == 0) {
 | 
			
		||||
		root = root->children[0];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								BinaryTree/BalanceTree/BPlus-Tree/Node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								BinaryTree/BalanceTree/BPlus-Tree/Node.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <vector>
 | 
			
		||||
template <class T>
 | 
			
		||||
class Node {
 | 
			
		||||
public:
 | 
			
		||||
	//ʹ<>õ<EFBFBD>ʱ<EFBFBD><CAB1>T<EFBFBD><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pair
 | 
			
		||||
	std::vector<T> keys;
 | 
			
		||||
	std::vector<Node<T>*> children;
 | 
			
		||||
	bool isLeaf;
 | 
			
		||||
	Node<T>* next;
 | 
			
		||||
 | 
			
		||||
	Node() = delete;
 | 
			
		||||
	Node(bool _isLeaf) : isLeaf(_isLeaf), next(nullptr) {}
 | 
			
		||||
	Node(bool _isLeaf, Node<T>* _next) : isLeaf(_isLeaf), next(_next) {}
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										25
									
								
								BinaryTree/BalanceTree/BPlus-Tree/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								BinaryTree/BalanceTree/BPlus-Tree/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
#include "BPlusTree.h"
 | 
			
		||||
using namespace std;
 | 
			
		||||
int main() {
 | 
			
		||||
	BPlusTree<int> tree(5);
 | 
			
		||||
	tree.insert(0);
 | 
			
		||||
	tree.insert(10);
 | 
			
		||||
	tree.insert(5);
 | 
			
		||||
	tree.insert(9);
 | 
			
		||||
	tree.insert(8);
 | 
			
		||||
	tree.insert(1);
 | 
			
		||||
	tree.insert(2);
 | 
			
		||||
	tree.insert(3);
 | 
			
		||||
	tree.insert(4);
 | 
			
		||||
	tree.displayLeaf();
 | 
			
		||||
	tree.areaSearch(2, 8);
 | 
			
		||||
	tree.erase(4);
 | 
			
		||||
	tree.displayLeaf();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
0 1 C 2 3 4 C 5 8 C 9 10 C
 | 
			
		||||
2 3 4 5 8
 | 
			
		||||
0 1 C 2 3 C 5 8 C 9 10 C
 | 
			
		||||
*/
 | 
			
		||||
@@ -312,3 +312,4 @@
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
要不要我帮你把“3 种情况 → 转化为 2 种简单情况”的流程画成一个 **决策图(删除流程图)**?这样会更直观。
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user