从10月14日b-树第1个版本,经过1天多的反复测试和修改,终于出了今天10月16日的最终版本,哈哈,b-树顺利拿下 template<class K, class E, int M> class BMTree { public: BMTree() {root = 0; height = 0;} ~BMTree() { } bool Search(const K& k, E& e) const; BMTree<K,E,M>& Insert(const E& e); BMTree<K,E,M>& Delete(const K& k, E& e); int GetHeight() const { return height; } void LevelOrder(void(*Visit)(BMTree_Node<K,E,M> *u)); void LevelOutput() {LevelOrder(Output); cout << endl;} public: static const int D = (M + 1)/2 ; //D为子节点的最少个数,元素最少个数是D-1 static const int COUNT_OF_FIRST = D - 1; //分裂节点时,第1个节点的元素个数 static const int COUNT_OF_SECOND = M - D; //分裂节点时,第2个节点的元素个数 private: BMTree_Node<K,E,M> *root; int height; BMTree_Node<K,E,M>* Search_Node(const K& k, int& index, bool& match) const; void Insert_Not_Full(BMTree_Node<K,E,M> *p, int index, const E& e); int Insert_Not_Full(BMTree_Node<K,E,M> *p, const E& e); void Split(BMTree_Node<K,E,M> *op, BMTree_Node<K,E,M> *np, E& es); void Delete_Leaf(BMTree_Node<K,E,M>* p, int index, const K& k, E& e); void Merge(BMTree_Node<K,E,M>* p); static void Output(BMTree_Node<K,E,M> *p); }; template<class K, class E, int M> bool BMTree<K,E,M>::Search(const K& k, E& e) const { BMTree_Node<K,E,M> *p = root; while(p) { int i = 0; for(;i < p->count && p->data[i] < k; i++) ; if( (i < p->count) && (p->data[i] == k) ) { e = p->data[i]; return true; } //下潜 p = p->child[i]; } return false; } template<class K, class E, int M> void BMTree<K,E,M>::Split(BMTree_Node<K,E,M> *op, BMTree_Node<K,E,M> *np, E& es) { int i = 0; for(; i < COUNT_OF_SECOND; i++) { np->data[COUNT_OF_SECOND-i-1] = op->data[M-i-1]; np->child[COUNT_OF_SECOND-i] = op->child[M-i]; op->child[M-i] = 0; if(np->child[COUNT_OF_SECOND-i]) { np->child[COUNT_OF_SECOND-i]->parent = np; np->child[COUNT_OF_SECOND-i]->index = COUNT_OF_SECOND-i; } } np->child[0] = op->child[M-i]; op->child[M-i] = 0; if(np->child[0]) { np->child[0]->parent = np; np->child[0]->index = 0; } es = op->data[D-1]; op->count = COUNT_OF_FIRST; np->count = COUNT_OF_SECOND; } template<class K, class E, int M> int BMTree<K,E,M>::Insert_Not_Full(BMTree_Node<K,E,M> *p, const E& e) { //assert(p); int i = 0; for(; i < p->count && p->data[i] < e; i++) ; for(int j = p->count-1; j >= i; j--) { p->data[j+1] = p->data[j]; p->child[j+2] = p->child[j+1]; if(p->child[j+2]) p->child[j+2]->index = j+2; } p->data[i] = e; p->count++; return i; } template<class K, class E, int M> BMTree<K,E,M>& BMTree<K,E,M>::Insert(const E& e) { if(!root) { BMTree_Node<K,E,M> *p = new BMTree_Node<K,E,M>; p->data[0] = e; p->count++; root = p; height = 1; return *this; } int index; bool match; BMTree_Node<K,E,M> *p = Search_Node(e, index, match); if(match) { throw BadInput(); } else { Insert_Not_Full(p,index,e); while( p->count == M ) { BMTree_Node<K,E,M> *np = new BMTree_Node<K,E,M>; //分裂 E _es; Split(p, np, _es); if( p != root ) { BMTree_Node<K,E,M> *pp = p->parent; index = Insert_Not_Full(pp, _es); p->index = index; np->index = index+1; pp->child[index] = p; pp->child[index+1] = np; np->parent = pp; p = pp; } else { BMTree_Node<K,E,M> *nh = new BMTree_Node<K,E,M>; nh->child[0] = p; p->parent = nh; p->index = 0; nh->child[1] = np; np->parent = nh; np->index = 1; nh->data[0] = _es; nh->count++; root = nh; height++; } } } return *this; } template<class K, class E, int M> void BMTree<K,E,M>::Insert_Not_Full(BMTree_Node<K,E,M> *p, int index, const E& e) { //assert(p); //assert(index >=0 && index < p->count); for(int j = p->count-1; j >= index; j--) { p->data[j+1] = p->data[j]; p->child[j+2] = p->child[j+1]; if(p->child[j+2]) p->child[j+2]->index = j+2; } p->data[index] = e; p->count++; } template<class K, class E, int M> BMTree_Node<K,E,M>* BMTree<K,E,M>::Search_Node(const K& k, int& index, bool& match) const { BMTree_Node<K,E,M> *p = root; match = false; index = -1; while(p) { for(index = 0; index < p->count && p->data[index] < k; index++) ; if( (index < p->count) && (p->data[index] == k) ) { match = true; return p; } if( p->child[index] == 0 ) return p; //下潜 p = p->child[index]; } return p; } template<class K, class E, int M> void BMTree<K,E,M>::Delete_Leaf(BMTree_Node<K,E,M>* p, int index, const K& k, E& e) { //assert(p); //保证p是叶节点 if( p->count > D - 1 || p == root ) { for(int i = index; i < p->count-1; i++ ) { p->data[i] = p->data[i+1]; } p->count--; if( p == root && p->count == 0 ) { delete p; root = 0; height = 0; } } else { //assert(p->parent!=0); //检查左兄弟 if( p->index > 0 && p->parent->child[p->index-1]->count > D - 1 ) { BMTree_Node<K,E,M>* left = p->parent->child[p->index-1]; //删除index元素,空出0位置 for(int i = index; i > 0; i-- ) { p->data[i] = p->data[i-1]; } p->data[0] = p->parent->data[p->index-1]; p->parent->data[p->index-1] = left->data[left->count-1]; left->count--; } //检查右兄弟 else if( p->index < p->parent->count && p->parent->child[p->index+1]->count > D - 1) { BMTree_Node<K,E,M>* right = p->parent->child[p->index+1]; //删除index元素,空出p->count-1位置 for(int i = index; i < p->count-1; i++ ) { p->data[i] = p->data[i+1]; } p->data[p->count-1] = p->parent->data[p->index]; p->parent->data[p->index] = right->data[0]; //右兄弟删除0元素 for(int i = 0; i < right->count-1; i++ ) { right->data[i] = right->data[i+1]; } right->count--; } else { if( p->index > 0 ) { BMTree_Node<K,E,M>* left = p->parent->child[p->index-1]; left->data[left->count++] = p->parent->data[p->index-1]; for(int i = 0; i < index; i++ ) { left->data[left->count++] = p->data[i]; } for(int i = index + 1; i < p->count; i++ ) { left->data[left->count++] = p->data[i]; } for( int i = p->index; i < p->parent->count; ++i ) { p->parent->data[i-1] = p->parent->data[i]; p->parent->child[i] = p->parent->child[i+1]; if( p->parent->child[i] ) p->parent->child[i]->index = i; } p->parent->count--; delete p; if( left->parent->count < D-1) Merge(left->parent); } else if( p->index < p->parent->count ) { BMTree_Node<K,E,M>* right = p->parent->child[p->index+1]; //删除index元素 for(int i = index; i < p->count-1; i++ ) { p->data[i] = p->data[i+1]; } p->count--; p->data[p->count++] = p->parent->data[p->index]; for(int i = 0; i < right->count; i++ ) { p->data[p->count++] = right->data[i]; } for( int i = p->index; i < p->parent->count-1; ++i ) { p->parent->data[i] = p->parent->data[i+1]; p->parent->child[i+1] = p->parent->child[i+2]; if( p->parent->child[i+1] ) p->parent->child[i+1]->index = i+1; } p->parent->count--; delete right; if( p->parent->count < D-1) Merge(p->parent); } } } } template<class K, class E, int M> void BMTree<K,E,M>::Merge(BMTree_Node<K,E,M>* p) { //assert(p->parent); //检查左兄弟 if( p->index > 0 && p->parent->child[p->index-1]->count > D - 1 ) { BMTree_Node<K,E,M>* left = p->parent->child[p->index-1]; //空出0位置 for(int i = p->count; i > 0; i-- ) { p->data[i] = p->data[i-1]; p->child[i+1] = p->child[i]; if( p->child[i+1] ) p->child[i+1]->index = i+1; } p->child[1] = p->child[0]; p->child[0] = left->child[left->count]; left->child[left->count] = 0; if( p->child[0] ) { p->child[0]->parent = p; p->child[0]->index = 0; } p->data[0] = p->parent->data[p->index-1]; p->count++; p->parent->data[p->index-1] = left->data[left->count-1]; left->count--; } //检查右兄弟 else if( p->index < p->parent->count && p->parent->child[p->index+1]->count > D - 1) { BMTree_Node<K,E,M>* right = p->parent->child[p->index+1]; p->data[p->count] = p->parent->data[p->index]; p->child[p->count+1] = right->child[0]; if( p->child[p->count+1] ) { p->child[p->count+1]->parent = p; p->child[p->count+1]->index = p->count+1; } p->count++; p->parent->data[p->index] = right->data[0]; //右兄弟删除0元素 for(int i = 0; i < right->count-1; i++ ) { right->data[i] = right->data[i+1]; right->child[i] = right->child[i+1]; if( right->child[i] ) right->child[i]->index = i; } right->child[right->count-1] = right->child[right->count]; right->child[right->count] = 0; if( right->child[right->count-1] ) right->child[right->count-1]->index = right->count-1; right->count--; } else { do { if( p->index > 0 ) { BMTree_Node<K,E,M>* left = p->parent->child[p->index-1]; left->data[left->count++] = p->parent->data[p->index-1]; left->child[left->count] = p->child[0]; if( left->child[left->count] ) { left->child[left->count]->parent = left; left->child[left->count]->index = left->count; } for(int i = 0; i < p->count; i++ ) { left->data[left->count++] = p->data[i]; left->child[left->count] = p->child[i+1]; if( left->child[left->count] ) { left->child[left->count]->parent = left; left->child[left->count]->index = left->count; } } for( int i = p->index; i < p->parent->count; ++i ) { p->parent->data[i-1] = p->parent->data[i]; p->parent->child[i] = p->parent->child[i+1]; if( p->parent->child[i] ) { p->parent->child[i]->index = i; } } p->parent->count--; delete p; if( left->parent == root && left->parent->count == 0 ) { left->parent = 0; delete root; root = left; height--; break; } else { p = left->parent; } } else if( p->index < p->parent->count ) { BMTree_Node<K,E,M>* right = p->parent->child[p->index+1]; p->data[p->count++] = p->parent->data[p->index]; p->child[p->count] = right->child[0]; if( p->child[p->count] ) { p->child[p->count]->parent = p; p->child[p->count]->index = p->count; } for(int i = 0; i < right->count; i++ ) { p->data[p->count++] = right->data[i]; p->child[p->count] = right->child[i+1]; if( p->child[p->count] ) { p->child[p->count]->parent = p; p->child[p->count]->index = p->count; } } for( int i = p->index; i < p->parent->count-1; ++i ) { p->parent->data[i] = p->parent->data[i+1]; p->parent->child[i+1] = p->parent->child[i+2]; if( p->parent->child[i+1] ) { p->parent->child[i+1]->index = i+1; } } p->parent->count--; delete right; if( p->parent == root && p->parent->count == 0 ) { p->parent = 0; delete root; root = p; height--; break; } else { p = p->parent; } } } while(p->count < D-1); } } template<class K, class E, int M> BMTree<K,E,M>& BMTree<K,E,M>::Delete(const K& k, E& e) { bool match = false; int index = -1; BMTree_Node<K,E,M> * p = Search_Node(k,index,match); if( !match ) throw BadInput(); //是否叶节点 if(!p->child[0]) { //是叶节点,直接删除 Delete_Leaf(p, index, k, e); return *this; } else { BMTree_Node<K,E,M> * tmp = p->child[index]; BMTree_Node<K,E,M> * tmpp = p; while(tmp) { //assert(tmp->count > 0) tmpp = tmp; tmp = tmp->child[tmp->count]; } p->data[index] = tmpp->data[tmpp->count-1]; Delete_Leaf(tmpp, tmpp->count-1, tmpp->data[tmpp->count-1], e ); } return *this; } template<class K, class E, int M> void BMTree<K,E,M>::Output(BMTree_Node<K,E,M> *p) { for( int i = 0; i < p->count; i++) { cout << p->data[i] << ' '; } } template<class K, class E, int M> void BMTree<K,E,M>::LevelOrder(void(*Visit)(BMTree_Node<K,E,M> *u)) { LinkedQueue<BMTree_Node<K,E,M>* > Q; BMTree_Node<K,E,M>* p = root; while (p) { Visit(p); if( p->child[0] ) { for( int i = 0; i <= p->count; i++) { Q.Add(p->child[i]); } } try { Q.Delete(p); } catch(OutOfBounds) { return; } } } //M叉B-树的节点 template<class K, class E, int M> struct BMTree_Node { static const int D = (M + 1)/2 ; //D为子节点的最少个数,元素最少个数是D-1 static const int COUNT_OF_FIRST = D - 1; //分裂节点时,第1个节点的元素个数 static const int COUNT_OF_SECOND = M - D; //分裂节点时,第2个节点的元素个数 int count; //此节点已存放的元素个数 int index; //是父节点第几个子节点 E data[M]; //M-1个元素,多一个是因为节点分裂操作 BMTree_Node<K,E,M> *child[M+1]; //M个子节点,多一个是因为节点分裂操作 BMTree_Node<K,E,M> *parent; //父节点 BMTree_Node() { count = 0; index = 0; memset( data, 0, sizeof(data)); memset( child, 0, sizeof(child)); parent = 0; } };