您的位置:首页 > 其它

二叉树系列之二:二叉搜索树

2007-01-01 19:50 274 查看
本文介绍了二叉搜索树的一些必要元素,包括:

search(T key):特定键值的查找;

minimum(): 树中最小键值的查找;

maximum():树中最大键值的查找;

successor(BTNode<T>* x):获得x的下一节点;

predeccessor(BTNode<T>* x):获得x的上一节点;

insert(T data):插入指定的键值;

remove(T data):删除指定的键值;

rotateLeft(BTNode<T>* x):对x节点进行向左旋转;

rotateRight(BTNode<T>* x):对x节点进行向右旋转。

下面是完整的代码:


#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.


virtual void 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


else if (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


virtual void 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


else if (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.


virtual void 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;


else if (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.


virtual void 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;


else if (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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: