分析:
原有的二叉搜索树删除流程分成两种情况:
(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;
}
其实就是更新三个结点,后继结点的各个指针,待删除结点的父结点的指针,待删除结点的孩子的指针