• [leetCode]450. 删除二叉搜索树中的节点


    递归

    需要想清楚五种情况如注释所示,利用递归的返回值来删除目标节点

    class Solution {
        public TreeNode deleteNode(TreeNode root, int key) {
            // 第一种情况,没有找到删除节点直接返回null
            if (root == null) return root;
            if (root.val == key) {
                // 第二种情况,左右孩子都为空(叶子节点)直接返回null
                // 第三种情况,左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
                if (root.left == null) return root.right;
                // 第四种情况,右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
                else if (root.right == null) return root.left;
                // 第五种情况,左右孩子都不为空,则将删除节点的左子树放到删除节点的右子树最左面节点的左孩子
                // 并返回删除节点的右孩子为新的根节点
                else {
                    TreeNode cur = root.right;
                    while (cur.left != null) { // 找到右子树最左面的节点
                        cur = cur.left;
                    }
                    cur.left = root.left; // 把要删除的节点的左子树放在cur的左孩子位置
                    root = root.right; // 返回root右孩子作为新root
                    return root;
                }
            }
            if (root.val > key) root.left = deleteNode(root.left, key);
            if (root.val < key) root.right = deleteNode(root.right, key);
            return root;
        }
    }
    

    使用删除二叉树节点的方法

    代码中目标节点(要删除的节点)被操作了两次:

    第一次是和目标节点的右子树最左面节点交换。
    第二次直接被NULL覆盖了。

    class Solution {
        public TreeNode deleteNode(TreeNode root, int key) {
            if (root == null) return root;
            if (root.val == key) {
                if (root.right == null) return root.left; // 这里是第二次操作目标值起到删除作用
                TreeNode cur = root.right;
                while (cur.left != null) {
                    cur = cur.left;
                }
                // 交换删除节点与删除节点右子树最左边节点的值
                swap(cur, root);
            }
            root.left = deleteNode(root.left, key);
            
            root.right = deleteNode(root.right, key);
            return root;
        }
    
        private void swap(TreeNode p, TreeNode q) {
            int tmp = p.val;
            p.val = q.val;
            q.val = tmp;
        }
    }
    

    迭代

    class Solution {
        public TreeNode deleteNode(TreeNode root, int key) {
            if (root == null) return root;
            TreeNode cur = root;
            TreeNode pre = null; // 记录父节点,用来删除cur
            while (cur != null) {
                if (cur.val == key) break;
                pre = cur;
                if (cur.val > key) cur = cur.left;
                else cur = cur.right;
            }
            if (pre == null) { // 如果搜索树只有头节点
                return deleteOneNode(cur);
            }
            // pre 要知道删除的是左孩子还是右孩子
            if (pre.left != null && pre.left.val == key) {
                pre.left = deleteOneNode(cur);
            }
            if (pre.right != null && pre.right.val == key) {
                pre.right = deleteOneNode(cur);
            }
            return root;
        }
    
        // 将目标节点的左子树连接到目标节点的右子树最左边的节点上
        // 返回目标节点的右孩子作为新的根节点
        private TreeNode deleteOneNode(TreeNode target) {
            if (target == null) return target;
            if (target.right == null) return target.left;
            TreeNode cur = target.right;
            while (cur.left != null) {
                cur = cur.left;
            }
            cur.left = target.left;
            return target.right;
        }
    }
    
  • 相关阅读:
    Django模板语言进阶
    ORM基础之ORM介绍和基础操作
    ORM关于表那些事
    ORM之基础操作进阶
    ORM基础之字段及其参数介绍
    AJAX初识(原生JS版AJAX和Jquery版AJAX)
    AJAX异步、sweetalert、Cookie和Session初识
    在一个千万级的数据库查寻中,如何提高查询效率?
    A fatal error has been detected by the Java Runtime Environment(jdk 1.6的一个BUG)
    外网映射工具地址
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13928981.html
Copyright © 2020-2023  润新知