1. 程式人生 > >B樹詳解

B樹詳解

#include <iostream>
using namespace std;

template<class K, size_t M>
struct BTreeNode
{
	typedef BTreeNode<K,M> Node;

	BTreeNode()
		:size(0)
		,_pParent(NULL)
	{}
	K _keys[M];  //關鍵字集合
	Node* _pSon[M+1];//孩子指標集合
	size_t size;
	Node* _pParent;
};

template<class K,size_t M>
class BTree
{
	typedef BTreeNode<K,M> Node;
public:
	BTree()
		:_pRoot(NULL)
	{}
bool Insert(const K&key)
{
	if (_pRoot == NULL)     //若樹為空
	{
		_pRoot = new Node();
		_pRoot->_keys[0] = key;
		_pRoot->size++;
		_pRoot->_pSon[0] = NULL;
		_pRoot->_pSon[1] = NULL;
		return true;
	}

	//找插入位置
	pair<Node*,int> s = Find(key);
	if (s.second != -1)   //已經存在
		return false;

	Node* pCur = s.first;
	Node* pSub = NULL;
	K key1 = key;
	while(true)
	{
		_Insertkey(pCur,key1,pSub);  //插入key值  pSub是插入的結點的孩子,若是新插入的,則pSub的值賦為NULL
                                              //若是往上調整的,則需要調整孩子

		if (pCur->size <M) //無需調整
			return true;
		else
		{
			size_t mid = pCur->size/2;   //分裂取中 

			Node* pNew = new Node();
			size_t count = 0;
			size_t idx ;
			for( idx = mid+1;idx<pCur->size;)
			{
				pNew->_keys[count] = pCur->_keys[idx];
				pNew->_pSon[count++] = pCur->_pSon[idx++]; 
			}
			pNew->_pSon[count] = pCur->_pSon[idx];
			pCur->size = pCur->size - mid - 1;
			pNew->size = count;


			if (pCur == _pRoot)   //若原結點是根節點
			{
				_pRoot = new Node();
				_pRoot->_keys[0] = pCur->_keys[mid];
				_pRoot->_pSon[0] = pCur;
				pCur->_pParent = _pRoot;
				_pRoot->_pSon[1] = pNew;
				pNew->_pParent = _pRoot;
				_pRoot->size++;
				return true;
			} 

			pSub = pNew;    //更新孩子指標
			key1 = pCur->_keys[mid];   //更新要插入的值
			pCur = pCur->_pParent;  向上調整
		}
	}

}

pair<Node*,int> Find(const K& key)   //若查詢失敗,則返回 NULL和-1 
{
	Node * pCur = _pRoot;
	Node* pParent = NULL;
	size_t idx = 0;
	while (pCur)
	{
		idx = 0;
		while (idx < pCur->size)
		{
			if (pCur->_keys[idx]<key )
				idx++;
			else if (pCur->_keys[idx]>key)
				break;
			else
				return make_pair(pCur,idx);
		}
		if (idx == pCur->size&&pCur->_pSon[idx] == NULL)
		{
			return make_pair(pCur,-1);
		}
		else
		{
			pParent = pCur;
			pCur = pCur->_pSon[idx];
		}
	}
	return make_pair(pParent,-1);
}
void InOrder()
{
	_InOrder(_pRoot);
}
private:
	void _InOrder(Node* &pRoot)
	{
		if (pRoot== NULL)
			return;

		size_t idx;
		for(idx =0 ;idx<pRoot->size;++idx)
		{
			_InOrder(pRoot->_pSon[idx]);
			cout<<pRoot->_keys[idx]<<" ";
		}
		_InOrder(pRoot->_pSon[idx]);
	}
	void _Insertkey(Node* &pCur,const K& key,Node* pSub)
	{
		size_t end = pCur->size -1;
		while(end >= 0)
		{
			if (pCur->_keys[end] >key)    //後搬
			{

				pCur->_keys[end+1]= pCur->_keys[end];
				pCur->_pSon[end+2] = pCur->_pSon[end+1];
				--end;
			}
			else
			{
				pCur->_keys[end+1] = key;
				pCur->_pSon[end+2] = pSub;
				++pCur->size;
				return;
			}
		}
		pCur->_keys[0] = key;
		pCur->_pSon[0] = pSub;
		++pCur->size;
	}
private:
	Node* _pRoot;
};