Árbol de búsqueda binaria: implementación BST

Este artículo ofrece la implementación en C ++ del árbol de búsqueda binaria. En algunos libros de texto, el árbol de búsqueda binaria también se denomina árbol de ordenamiento binario. Hay muchas variantes de esta estructura de árbol, como BBST, AVLTree, RBTree, etc. Los datos se presentan de manera razonable para que la secuencia de resultados atravesada en el orden medio se organice en orden ascendente de los valores del código clave, de modo que la eficiencia de acceso de un elemento sea lo más cercana posible a la complejidad logarítmica del tiempo, pero el BST simple mencionado en este artículo En términos de, no existe un proceso de equilibrio de subárbol izquierdo y derecho para ningún nodo, por lo que en algunos casos extremos, BST degenera en un "árbol sesgado" del tipo "lista listada", por lo que, desde el punto de vista de la eficiencia, no está optimizado Ya sea que se haya insertado o accedido al BST, eliminar y otras operaciones no pueden lograr nuestros resultados satisfactorios, para resolver este problema, las personas han propuesto sucesivamente AVL, RBTree y otras estructuras de datos, utilizando diferentes estrategias para hacer frente Las operaciones mencionadas se optimizan tanto como sea posible a tiempo.

#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;
}
Publicado 27 artículos originales · ganó 23 · vistas 256

Supongo que te gusta

Origin blog.csdn.net/dosdiosas_/article/details/105578686
Recomendado
Clasificación