(略难)二叉查找树的删除

Posted jun10ng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(略难)二叉查找树的删除相关的知识,希望对你有一定的参考价值。

这是一道想起来简单,但是实现起来困难的题目,因为要考虑的情况有点多
https://www.lintcode.com/problem/remove-node-in-binary-search-tree/
1.删除节点是叶节点,直接删除
2.删除节点是非叶节点,且非满节点,可用其子树节点取代
3.删除节点是满节点
首先找到其后续节点(中序遍历下一个,即其右子树的最左节点)
3.1如果后续节点和删除节点是相邻两层,即后续节点是删除节点的右子树。则直接将后续节点赋值给删除节点,记得相关父子节点关系理清,(删除节点的左子树等)
3.2如果后续节点和删除节点不在相邻层,这个情况下直接更改删除节点中的value,然后理清后续节点的子树关系,虽然后续节点是最左节点,但他也有可能有右子树。这个时候需要将后续节点的子树赋值给其父节点。

注意要点:
1.在写程序时,开头就要有一个意识,就是时刻保存三个值,父节点,现节点,和子树。
2.判断是否为3.1情况的条件为tmp->right->left==NULL,如果不是再开始进行while循环找到最左节点。

class Solution {
public:
    /**
     * @param root: The root of the binary search tree.
     * @param value: Remove the node with given value.
     * @return: The root of the binary search tree after removal.
     */
    TreeNode* removeNode(TreeNode* root, int value) {
        // write your code here
        if (root == NULL)
            return NULL;
        TreeNode * head = new TreeNode();
        head->left = root;
        TreeNode * tmp = root, *father = head;

        while (tmp != NULL) {
            if (tmp->val == value)
                break;
            father = tmp;
            if (tmp->val > value)
                tmp = tmp->left;
            else
                tmp = tmp->right;
        }
        if (tmp == NULL)
            return head->left;

        if (tmp->right == NULL) {
            if (father->left == tmp)
                father->left = tmp->left;
            else
                father->right = tmp->left;
        } else 
        if (tmp->right->left == NULL) {
            if (father->left == tmp)
                father->left = tmp->right;
            else
                father->right = tmp->right;

            tmp->right->left = tmp->left;
            
        } else {
            father = tmp->right;
            TreeNode * cur = tmp->right->left;
            while (cur->left != NULL) {
                father = cur;
                cur = cur->left;
            }
            tmp->val = cur->val;
            father->left = cur->right;
        }
        return head->left;
    }
};

以上是关于(略难)二叉查找树的删除的主要内容,如果未能解决你的问题,请参考以下文章

重温数据结构:二叉排序树的查找插入删除

C++-二叉搜索树的查找&插入&删除-二叉搜索树代码实现-二叉搜索树性能分析及解决方案

二叉排序树的定义及基本操作(构造查找插入删除)递归及非递归算法

二叉排序树的查找插入删除

二叉查找树中元素的删除操作

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段