本题我自己做只得了80%左右,主要是删除根节点时没处理好。
这一题我吸取的上一题的教训,用了二叉搜索树的特性:
左节点小于根节点
右节点大于根节点
所以我们的递归还是得使用三个主判断:
小于、大于、等于指定元素时怎么做:
根节点值小于指定元素时,就说明在需要删除的元素在右边、向右递归
根节点值大于指定元素时,就在左边、向左递归。
等于时,就要进行删除操作:
分为三个条件:
1、待删除节点左、右节点都是空时,就说明是叶子节点,后面什么都没了,直接返回null。
2、左节点为空或者右节点为空,就说明需要返回非空节点下面的子树,将非空的节点子树返回就好了。
3、左、右节点都不为空时,这个时候就比较麻烦了:删除节点后,要保持二叉搜索树的特性,所以就得怎么做:
将待删除节点的左节点全部加入到待删除节点右子树的左子叶上、
因为删除节点的右节点一定比左节点大,而且它也是二叉搜索树,它的左节点一定是整颗二叉树合理的地方。
package shuJuJieGouYuSuanFa.erChaShu;
public class likou450 {
public static void main(String[] args) {
TreeNode root = TreeNode.getBST();
int key = 8;
TreeNode ans = new likou450().deleteNode(root, key);
peint(ans);
}
//打印输出二叉树,前序遍历
private static void peint(TreeNode ans) {
if (ans == null) {
return;
}
System.out.print(ans.val + " ");
peint(ans.left);
peint(ans.right);
}
public TreeNode deleteNode(TreeNode root, int key) {
return dfs(root, key);
}
private TreeNode dfs(TreeNode root, int key) {
if (root == null) {
return null;
}
if (root.val < key) {
root.right = dfs(root.right, key);
} else if (root.val > key) {
root.left = dfs(root.left, key);
} else {
if (root.left == null && root.right == null) {
return null;
} else if (root.left == null) {
return root.right;
} else if (root.right == null) {
return root.left;
} else if (root.left != null && root.right != null) {
TreeNode t = root.right;
while (t.left != null) {
t = t.left;
}
t.left = root.left;
root = root.right;
return root;
}
}
return root;
}
}
难度还是有点的,自己带得努力,暗自加油吧!