数据结构的运算之查找(二)

本文详细探讨了二叉排序树的查找、插入、删除操作,包括查找算法核心思路、平均查找长度分析,以及删除结点的复杂策略。通过实例演示和代码实现,帮助理解如何构建和维护这种高效的数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前面分享完循序表的查找算法后,今天我们来看看树表中的二叉排序树的相关操作吧

1.二叉排序树的查找操作

二叉排序树的查找算法核心思路:

实现代码:

该算法分析 

二叉排序树的平均查找长度的分析: 

 2.二叉排序树的插入操作 :

算法实现:

void InsertBST(BSTree &T,ElemType e){
    if(!T){
        S=new BSTNode;
        S->data=e;
        s->lchild=S->rchild=NULL;
        T=S;
    }
    else if(e.key<T->data.key) InsertBST(T->lchild,e);
    else if(e.key>T->data.key) InsertBST(T->rchild,e);
}

3.二叉树的生成操作: 

注意:不同插入次序的序列生成不同形态的二叉排序树

算法实现:

void CreatBST(BSTree &T){
    T=NULL;
    cin>>e;
    while(e.key!=ENDFLAG){    //ENDFLAG为自定义的输入结束标志
        InsertBST(T,e);    //将此结点插入二叉排序树中
        cin>>e;
    }
}

4.二叉排序树的删除操作:

 

 

 这种情况比较麻烦,如图要删掉50这个结点,要利用该50结点的中序遍历前驱节点(如图的40结点)去替代它。

结果如图所示: 

另一种解法:用如图的80结点(可以理解为右子树最小值结点)替代50结点,

 

 具体算法实现:

int Delete(BiTree *p)
{
    BiTree q, s;
    //情况 1,结点 p 本身为叶子结点,直接删除即可
    if (!(*p)->lchild && !(*p)->rchild)
    {
        *p = NULL;
    }
    //左子树为空,只需用结点 p 的右子树根结点代替结点 p 即可;
    else if (!(*p)->lchild)
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
        q = NULL;
    }
    //右子树为空,只需用结点 p 的左子树根结点代替结点 p 即可;
    else if (!(*p)->rchild)
    {
        q = *p;
        //这里不是指针 *p 指向左子树,而是将左子树存储的结点的地址赋值给指针变量 p
        *p = (*p)->lchild;
        free(q);
        q = NULL;
    }
    //左右子树均不为空,采用第 2 种方式
    else
    {
        q = *p;
        s = (*p)->lchild;
        //遍历,找到结点 p 的直接前驱
        while (s->rchild)
        {
            //指向p节点左子树最右边节点的前一个。保留下来
            q = s;
            s = s->rchild;
        }
        //直接改变结点 p 的值
        (*p)->data = s->data;
        //判断结点 p 的左子树 s 是否有右子树,分为两种情况讨论  如果有右子树,s一定会指向右子树的叶子节点。q 此时指向的是叶子节点的父节点。 q != *p二者不等说明有右子树
        if (q != *p)
        {
            //若有,则在删除直接前驱结点的同时,令前驱的左孩子结点改为 q 指向结点的孩子结点
            q->rchild = s->lchild;
        }
        else
        //q == *p ==NULL 说明没有右子树
        {
            //否则,直接将左子树上移即可
            q->lchild = s->lchild;
        }
        free(s);
        s = NULL;
    }
    return TRUE;
}
int DeleteBST(BiTree *T, int key)
{
    if (!(*T))
    { //不存在关键字等于key的数据元素
        return FALSE;
    }
    else
    {
        if (key == (*T)->data)
        {
            Delete(T);
            return TRUE;
        }
        else if (key < (*T)->data)
        {
            //使用递归的方式
            return DeleteBST(&(*T)->lchild, key);
        }
        else
        {
            return DeleteBST(&(*T)->rchild, key);
        }
    }
}
好啦,关于二叉排序树的内容就分享到这啦

本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值