#ifndef _BS_TREE_H_ #define _BS_TREE_H_ #include "BTree.h" template <class T> class BSTree : public BTree<T> ...{ public: BSTree(T data = T()) : BTree(data), avlnode_(BTNode<T>::nil()), rbnode_(BTNode<T>::nil())...{ } virtual~BSTree() ...{ } public: BTNode<T>* search(T key) ...{ return search(root_, key); } BTNode<T>* minimum() ...{ return minimum(root_); } BTNode<T>* maximum() ...{ return maximum(root_); } BTNode<T>* successor(BTNode<T>* x) ...{ if (x->rchild_ != BTNode<T>::nil()) return minimum(x->rchild_); BTNode<T>* y = x->parent_; while (y != BTNode<T>::nil() && x == y->rchild_) ...{ x = y; y = x->parent_; } return y; } BTNode<T>* predeccessor(BTNode<T>* x) ...{ if (x->lchild_ != BTNode<T>::nil()) return maximum(x->lchild_); BTNode<T>* y = x->parent_; while (y != BTNode<T>::nil() && x == y->lchild_) ...{ x = y; y = x->parent_; } return y; } // The pointer x traces the path, and the pointer y is maintained as the parent of x. // After initialization, the while loop in lines 3-7 causes these two pointers to move down the // tree, going left or right depending on the comparison of key[z] with key[x], until x is set to // NIL. This NIL occupies the position where we wish to place the input item z. Lines 8-13 set // the pointers that cause z to be inserted. virtualvoid insert(T data) ...{ BTNode<T>* y = BTNode<T>::nil(), *x = root_; // x traces the path, until x is set to BTNode<T>::nil(), // and y is the parent of x, and at last // y must be a leaf node with no child while (x != BTNode<T>::nil()) ...{ y = x; if (data < x->data_) x = x->lchild_; else x = x->rchild_; } BTNode<T>* z =new BTNode<T>(data); // Insert the z here, let y be the parent of z z->parent_ = y; // specify the current node for avltree and rbtree avlnode_ = z->parent_; rbnode_ = z; // let z be the child of y // y is BTNode<T>::nil(), this is an empty tree if (y == BTNode<T>::nil()) root_ = z; // insert z as y's left child elseif (data < y->data_) y->lchild_ = z; // insert z as y's right child else y->rchild_ = z; } // (a) If z has no children, we just remove it. // (b) If z has only one child, we splice out z. // (c) If z has two children, we splice out its successor y, // which has at most one child, and then replace z's key // and satellite data with y's key and satellite data virtualvoid remove(T data) ...{ BTNode<T>*y = BTNode<T>::nil(), *x = BTNode<T>::nil(); BTNode<T>*z = search(data); // can't find the node with data if (z == BTNode<T>::nil()) return; // at most one child, remove z or splice out z if (z->lchild_ == BTNode<T>::nil() || z->rchild_ == BTNode<T>::nil()) y = z; // two children, spice out its successor y else y = successor(z); // here we find the child to point when we spice out y if (y->lchild_ != BTNode<T>::nil()) x = y->lchild_; else x = y->rchild_; // spice out y and specify the new parent of child if (x != BTNode<T>::nil()) x->parent_ = y->parent_; // specify the current node for rbtree and avltree if (y->color_ == BLACK) rbnode_ = y->parent_; else rbnode_ = BTNode<T>::nil(); avlnode_ = y->parent_; // here we specify the new child of parent // y is root if (y->parent_ == BTNode<T>::nil()) root_ = x; // y is left child elseif (y == y->parent_->lchild_) y->parent_->lchild_ = x; // y is right child else y->parent_->rchild_ = x; // when y is a successor and be spiced out, // so we replace the z's data with y's data // and looks like z is deleted if (y != z) z->data_ = y->data_; delete y; } protected: // transforms the configuration of the two nodes on the left into the // configuration on the right by changing a constant number of pointers. virtualvoid rotateLeft(BTNode<T>* x) ...{ // the the node is nil_, can't rotate if (x != BTNode<T>::nil()) ...{ BTNode<T>*y = x->rchild_; // Turn y's left subtree into x's right subtree x->rchild_ = y->lchild_; if (y->lchild_ != BTNode<T>::nil()) y->lchild_->parent_ = x; // Link x's parent to y y->parent_ = x->parent_; if (x->parent_ == BTNode<T>::nil()) root_ = y; elseif (x == x->parent_->lchild_) x->parent_->lchild_ = y; else x->parent_->rchild_ = y; // Put x on y's left y->lchild_ = x; // let y be the parent of x x->parent_ = y; } BTNode<T>::nilify(); } // transforms the configuration of the two nodes on the right into the // configuration on the left by changing a constant number of pointers. virtualvoid rotateRight(BTNode<T>* x) ...{ // the the node is nil_, can't rotate if (x != BTNode<T>::nil()) ...{ BTNode<T>*y = x->lchild_; // Turn y's left subtree into x's right subtree x->lchild_ = y->rchild_; if (y->rchild_ != BTNode<T>::nil()) y->rchild_->parent_ = x; // Link x's parent to y y->parent_ = x->parent_; if (x->parent_ == BTNode<T>::nil()) root_ = y; elseif (x == x->parent_->lchild_) x->parent_->lchild_ = y; else x->parent_->rchild_ = y; // Put x on y's right y->rchild_ = x; // let y be the parent of x x->parent_ = y; } BTNode<T>::nilify(); } private: BTNode<T>* search(BTNode<T>* x, T key) ...{ while (x != BTNode<T>::nil() && x->data_ != key) ...{ if (key < x->data_) x = search(x->lchild_, key); else x = search(x->rchild_, key); } return (x->data_ == key) ? x : BTNode<T>::nil(); } BTNode<T>* minimum(BTNode<T>* x) ...{ while (x->lchild_ != BTNode<T>::nil()) x = x->lchild_; return x; } BTNode<T>* maximum(BTNode<T>* x) ...{ while (x->rchild_ != BTNode<T>::nil()) x = x->rchild_; return x; } protected: BTNode<T>* avlnode_; BTNode<T>* rbnode_; }; #endif