查找之三:二叉排序树(续)

本文深入解析了二叉排序树中删除节点的三种情况:叶子节点、单子树节点和双子树节点。通过递归方式查找目标节点并进行相应的删除操作。详细解释了每种情况的实现过程及注意事项。

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

上一篇(传送门:http://blog.youkuaiyun.com/xjtuse2014/article/details/51175592)关于二叉排序树的博客中,没有提到怎么删除一个节点,实际上,这也是BST(Binary Sort Tree)中稍微比较难一点的操作,但是,仔细分析的话,也很是很好理解的~~
先分析我们可能删除的结点属于哪种类型:


 1. 叶子结点
 2. 仅有左或右子树的结点
 3. 左右子树都有结点

面对上面提到的1,2两种情况,直接删除就好了,注意释放空间;第三种情况时,就用递归方式对二叉排序树T查找key,查找到时就删除。

/*
* 若二叉排序树T中存在关键字等于key的数据元素时,删除该结点
* 并返回true,否则返回false 
*/
bool DeleteBST(BiTree* T,int key){
    if(!*T){
        return false;//不存在关键字等于key的元素
    }else{
        if(key == T->data)//找到关键字等于key的数据元素
            return Delete(T);
        else if(key < T->data){
            return DeleteBST(T->lchild,key);
        else
            return DeleteBST(T->rchild,key);
        }
    }
}

下面的代码则是Delete():

//从二叉排序树中删除结点,并重接它的左或右子树
//左右子树都空和判断出只有一边为空的效果是一样的~~,所以这里没有单独列出这种情况
bool Delete(BiTree* p){
    BiTree q,s;
    if(p->rchild == NULL){   //右子树空则只需重接它的左子树
        q = *p;
        *p = (*p).lchild;
        free(q);
    }else if(p->lchild == NULL){   //左子树空则只需重接它的左子树
        q = *p;
        *p = (*p).rchild;
        free(q);
    }else{   //左右子树都不空
        q = *p;
        s = p->lchild;  
        while(s -> rchild){//转左,然后向右到尽头(找到待删除系结点的前驱)
            q = s;
            s = s->rchild;      
        }
        p->data = s->data; //s此时指向被删除结点的直接前驱
        if(q!=p)
            q -> rchild = s->lchild;//重接q的右子树
        else
            q->lchild = s->lchild;//重接q的左子树
        free(s);
    }
}

需要说明的是,对于第三种情况,我们的前驱来源是中序遍历了这个树,形成了一个顺序表,然后用待删除结点的前驱来代替它,因为这是他左边比他小但最接近它的一个数,当然,使用后继代替也是可以的。~~
对于这个不是很清楚的,先看看算法导论或者百度百科入个门:http://baike.baidu.com/link?url=70jU4KqcR5CY7iat43Cop4qaefwxtxXNxDnwzzUWANgIWiewnvQfRKT6XcPBEGQ4F_K-6E4JP_RtlF2RUVE0pK

欢迎交流~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值