思考问题的时候一定要跳出之前的思维圈,一旦出错,就会一直困在里面!!!!
删除二叉搜索树,在学数据结构的时候用C语言手敲了一遍。现在用Java来实现,发现毫无头绪!!!于是又在回忆之前的思路,结果越想越乱。
然后完全抛弃之前的想法,开始独立思考。随便指定实例中的一个节点的时候,就发现了三种情况,俺就是这个节点可能含有左右儿子中的一个,或者两个都有,或者根本就没有儿子节点。那么对于不同的情况就要有不同的应对方式。
对于树的形状的改变,有两种方法。
第一种方法是,直接将有儿子替换当前节点,然后将当前节点的左儿子放在右儿子的最小节点的左儿子上。
第二种是将右儿子中的最小节点替换掉要被删除的节点。
下面是第一种方法(自己想的)
第一步肯定是dfs查找到目标节点,找到之后便要开始分析这个节点的具体情况。
if (root.left == null && root.right == null) {
return null;
}
if (root.left == null || root.right == null) {
return root.left == null ? root.right : root.left;
}
root.right = insert(root.right, root.left);
root = root.right;
第三步中,为什么要设置这样一个插入方法?因为在写出方法之前,曾经直接遍历到right中的最小节点,然后将root.left放在这个节点的左儿子上,但是发现了一个问题,那就是返回的时候节点并没有发生改变。所以这里用了一个递归生成一个新的子树,并将这个新子树替换掉当前子树。下面是完整代码。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
TreeNode ans = dfs(root, key);
return ans;
}
public TreeNode dfs(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val) {
root.left = dfs(root.left, key);
}
if (key > root.val) {
root.right = dfs(root.right, key);
}
if (root.val == key) {
if (root.left == null && root.right == null) {
return null;
}
if (root.left == null || root.right == null) {
return root.left == null ? root.right : root.left;
}
root.right = insert(root.right, root.left);
root = root.right;
}
return root;
}
public TreeNode insert(TreeNode node, TreeNode left) {
if (node == null) {
node = left;
return node;
}
node.left = insert(node.left, left);
return node;
}
}
下面是第二种方法,按照大佬思路写的。前段部分的思路和之前是样的,不同的只有在找到节点之后的做法。直接找到右子树中最小的值的,然后修改当前root的值,最后调用delete方法删除掉这个最小的值。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
TreeNode ans = dfs(root, key);
return ans;
}
public TreeNode dfs(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val) {
root.left = dfs(root.left, key);
}
if (key > root.val) {
root.right = dfs(root.right, key);
}
if (root.val == key) {
if (root.left == null && root.right == null) {
return null;
}
if (root.left == null || root.right == null) {
return root.left == null ? root.right : root.left;
}
/*root.right = insert(root.right, root.left);
root = root.right;*/
int val = findMin(root.right);
root.val = val;
root.right = deleteNode(root.right, val);
}
return root;
}
public int findMin(TreeNode node) {
if (node.left == null) {
return node.val;
}
return findMin(node.left);
}
}