debug分析 删除二叉搜索树中的节点流程

题目背景

在基础比较差的情况下,对这个题目的理解时候有点问题,于是通过debug的方法倒推出出题的思路,反之回来思考就变得很清晰。话不多说,见实例:
原题链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/description/

题目描述

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
示例:

root = [8,5,6,3,7,null,9]
key = 5

    8
   / \
  5   6
 / \   \
3   7   9

给定需要删除的节点值是 5,所以我们首先找到 5 这个节点,然后删除它。

一个正确的答案是 [8,7,6,3,null,null,9], 如下图所示。

    8
   / \
  7   6
 /     \
3       9

另一个正确答案是 [8,3,6,null,7,null,9]8
   / \
  3   6
   \   \
    7   9
思路

step1:假如没有子节点,直接删除
step2:假如要删除的节点只有一个子节点,那么删除节点后,就用这个子节点替换
step3:假如要删除的节点有两个子节点,那么从删除节点的右分支查找最小值,将其要删除的节点替换

来,直接上代码:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        if (key < root.val){
            root.left = deleteNode(root.left,key);
            return root;
        }else if (key > root.val){
            root.right = deleteNode(root.right,key);
            return root;
        }else {
            if (root.left == null || root.right == null){
                root = root.left == null?root.right:root.left;
            }else {
                TreeNode cur = root.right;
                while (cur.left != null){
                    cur = cur.left;
                }
                root.val = cur.val;
                root.right = deleteNode(root.right,cur.val);
            }
        }
        return root;
    }
}

先用暂时能想到的粗鄙的方式给树赋值,然后咱们开始debug

public static void main(String[] args) {
        Solution solution = new Solution();
        TreeNode treeNode1 = new TreeNode(8);
        TreeNode treeNode2 = new TreeNode(5);
        TreeNode treeNode3 = new TreeNode(6);
        TreeNode treeNode4 = new TreeNode(3);
        TreeNode treeNode5 = new TreeNode(7);
        TreeNode treeNode6 = new TreeNode(9);
        treeNode1.left = treeNode2;
        treeNode1.right = treeNode3;
        treeNode2.left = treeNode4;
        treeNode2.right = treeNode5;
        treeNode3.left =null;
        treeNode3.right = treeNode6;
        TreeNode treeNode = solution.deleteNode(treeNode1, 5);
}

首先,root.val的值是8,小于key的值5,进入迭代

在这里插入图片描述
这个时候,root.val就是5了,这时候就进入下一个分支,首先判断是否有子分支,这时候的判断是有子分支的,然后我们这里判断右分支是否有左分支,如果有的话要继续迭代,没有的话那么我们就将右分支的值覆盖要删除的值,可以看到这时候,我们的右分支就替代了原来的要删除的位置。

在这里插入图片描述

但是右分支有个7,发现没有删除,那么我们就要来操作右分支,继续往下迭代,

在这里插入图片描述

在这里插入图片描述

重新走到这一步,发现没有子分支了,那么就会给他一个null。这时候,顺序就对上了。跟着这个思路走,可以理清操作流程。
当对这类题目有了明确的思路,可以自己走得通流程图,那么就不需要通过这种方式来理解,可以通过自己的思路,去更好的探究这些题目。
希望可以帮到你!

发布了5 篇原创文章 · 获赞 3 · 访问量 99

猜你喜欢

转载自blog.csdn.net/weixin_42887211/article/details/102916542
今日推荐