B樹詳解
阿新 • • 發佈:2018-12-25
#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; };