算法导论12.3-4 修改二叉树删除函数,确保结点被引用时删除不会出问题

分析:

原有的二叉搜索树删除流程分成两种情况:


(1) 当删除结点的度数小于2,即删除结点最多只有一个孩子,直接删除此结点,然后将其父结点指向删除结点的孩子


(2) 当删除结点的度数等于2,找到删除结点的后继结点,删除此后继结点,然后将更新删除结点的key和数据为后续结点的相应值,

这种删除方法会导致某个key对应的结点指针发生变化,如果结点指针被别的结构引用了,就会出问题


分析:

有两种解决方案

(1) bst_delete 函数返回真正删除的结点指针,引用结点指针的模块需要关注,并修正

(2) 修改bst_delete 函数,当删除结点的度数等于2时,不删除后续结点,将后续结点取代删除结点的位置


代码

struct bst_node *bst_delete(struct bst_node **root, struct bst_node *node)
{
    struct bst_node *one_degree, *child, *parent;

    if (node->left == NULL || node->right == NULL) {
        one_degree = node;
    }
    else {
        one_degree = bst_successor(node);
    }

    if (one_degree->left) {
        child = one_degree->left;
    }
    else {
        child = one_degree->right;
    }

    if (child)
        child->parent = one_degree->parent;

    if (one_degree->parent == NULL) {
        *root = child;
    }
    else {
        parent = one_degree->parent;
        if (parent->left == one_degree)
            parent->left = child;
        else
            parent->right = child;
    }

    if (one_degree != node) {
        /* update parent */
        one_degree->parent = node->parent;
        if (node->parent) {
            if (node->parent->left == node)
                node->parent->left = one_degree;
            else
                node->parent->right = one_degree;
        }
        else {
            *root = one_degree;
        }
        /* update child */
        one_degree->left = node->left;
        one_degree->right = node->right;
        if (node->left) {
            node->left->parent = one_degree;
        }
        if (node->right) {
            node->right->parent = one_degree;
        }
    }
    return node;
}
其实就是更新三个结点,后继结点的各个指针,待删除结点的父结点的指针,待删除结点的孩子的指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值