Binary search tree: BST implementation

This article gives the C ++ implementation of the binary search tree. In some textbooks, the binary search tree is also called the binary sort tree. There are many variants of this tree structure, such as BBST, AVLTree, RBTree, etc. The data is laid out reasonably so that the result sequence traversed in middle order is arranged in ascending order of key code values, so that the access efficiency of an element is as close to the logarithmic time complexity as possible, but the simple BST mentioned in this article In terms of, there is no left and right subtree balancing process for any node, so in some extreme cases, BST degenerates into a "listed list" type "skew tree", so purely from the perspective of efficiency, it is not optimized Whether the BST has been inserted or accessed, delete and other operations can not achieve our satisfactory results, in order to solve this problem, people have successively proposed AVL, RBTree and other data structures, using different strategies to make the front The mentioned operations are optimized as much as possible in time.

#include"BinTree.h"

using namespace std;


template <typename T> 
class BST : public BinTree<T> 
{ 
    //由BinTree派生BST模板类
    protected:
        BinNodePosi(T) _hot; //“命中”节点的父亲
 
    public: //基本接口:以virtual修饰,强制要求所有派生类(BST变种)根据各自的规则对其重写
        virtual BinNodePosi(T)& search(const T& e); //查找
        virtual BinNodePosi(T) insert(const T& e); //插入
        virtual bool remove(const T& e); //删除

};


template <typename T>
BinNodePosi(T)& BST<T>::search(const T& e) 
{
    //在BST中查找关键码e
    if (!BinTree<T>::_root || e == BinTree<T>::_root->data) 
    { 
        _hot = NULL;
        return BinTree<T>::_root; 
    } //在树根v处命中

    for (_hot = BinTree<T>::_root; ; ) 
    { 
        //自顶而下
        BinNodePosi(T)& c = (e < _hot->data) ? _hot->lc : _hot->rc; //确定方向
        if (!c || e == c->data)
        {
            return c;
        }
        _hot = c; //命中返回,或者深入一层
    } //无论命中或失败,hot均指向v之父亲(或为NULL)
} //返回目标节点位置的引用,以便后续插入、删除操作


template <typename T>
bool BST<T>::remove(const T& e) 
{ 
    //从BST树中删除关键码e
    BinNodePosi(T)& x = search(e); 
    if (!x)
    {
        return false; //确认目标存在(留意_hot的设置)
    }
    removeAt(x, _hot);
    BinTree<T>::_size--; //实施删除
    BinTree<T>::updateHeightAbove(_hot); //更新_hot及其历代祖先的高度
    return true;
} //删除成功与否,由返回值指示


template <typename T>
static BinNodePosi(T) removeAt(BinNodePosi(T)& x, BinNodePosi(T)& hot) 
{
    BinNodePosi(T) w = x; //实际被摘除的节点,初值同x
    BinNodePosi(T) succ = NULL; //实际被删除节点的接替者
    if (!HasLChild(*x)) //若*x的左子树为空,则可
    {
        succ = x = x->rc; //直接将*x替换为其右子树
    }
    else if (!HasRChild(*x)) //若右子树为空,则可
    {
        succ = x = x->lc; //对称地处理——注意:此时succ != NULL
    }
    else 
    { //若左右子树均存在,则选择x的直接后继作为实际被摘除节点,为此需要
        w = w->succ(); //(在右子树中)找到*x的直接后继*w
        swap(x->data, w->data); //交换*x和*w的数据元素
        BinNodePosi(T) u = w->parent;
        ((u == x) ? u->rc : u->lc) = succ = w->rc; //隔离节点*w
    }
    hot = w->parent; //记录实际被删除节点的父亲
    if (succ)
    {
        succ->parent = hot; //并将被删除节点的接替者与hot相联
    }
    release(w->data); 
    release(w);
    return succ; //释放被摘除节点,返回接替者
} //release()负责释放复杂结构,与算法无直接关系,具体实现详见代码包



template <typename T>
BinNodePosi(T) BST<T>::insert(const T& e) 
{ //将关键码e插入BST树中
    BinNodePosi(T)& x = search(e); 
    if (x)
    {
        return x; //确认目标不存在(留意对_hot的设置)
    }
    x = new BinNode<T>(e, _hot); //创建新节点x:以e为关键码,以_hot为父
    BinTree<T>::_size++; //更新全树规模
    BinTree<T>::updateHeightAbove(x); //更新x及其历代祖先的高度
    return x; //新插入的节点,必为叶子
} //无论e是否存在于原树中,返回时总有x->data == e



int main()
{
    BST<int>obj;
    obj.insert(1);
    obj.insert(10);
    obj.insert(5);
    obj.travIn(visit<int>);
    cout << endl;
    if (!obj.search(5))
    {
        cout << "element 5 not found!" << endl;
    }
    obj.remove(1);
    if (obj.empty())
    {
        cout << "Tree is empty"<<endl;
    }
    getchar();
    return 0;
}
Published 27 original articles · won 23 · views 256

Guess you like

Origin blog.csdn.net/dosdiosas_/article/details/105578686