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

来源:互联网 发布:ubuntu ati显卡驱动 编辑:程序博客网 时间:2024/05/16 09:39

本文介绍了二叉搜索树的一些必要元素,包括:

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(), *= 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> *= BTNode<T>::nil(), *= BTNode<T>::nil();
        BTNode
<T> *= 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> *= 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> *= 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
原创粉丝点击