LeetCode—450. Delete Node in a BST
题目
https://leetcode.com/problems/delete-node-in-a-bst/
删除搜索二叉树中的一个节点,返回新的搜索二叉树,因为结果不唯一,任意返回一个即可。
解析及代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
/**
使用迭代的话删除那个节点之后还需要重新连接其父节点指针, 也就是需要记录父节点. 这样的话就变得很麻烦, 因为还有一些特殊的情况,
比如要删除的节点是根节点, 或者还需要记录 当前节点是父节点的左子树还是右子树.
在此时递归就体现了其优越性, 因为递归是可以回溯的, 所以不需要记录父节点. 然后考虑删除以后节点的替换
递归的方法 分情况讨论
因为是用递归,我们先来看root是否是要铲除的节点
如果不是,我们要看是要删除左子树还是右子树上的节点,判断方法就是比较大小了,接着递归就行了
然后如果root是要删除的节点,这就要进一步分情况了
如果root的左子树或者右子树有一个是空的,那么简单,直接返回另一个不为空的子树就行了
如果root的左右子树都是空,那么也简单,说明是叶子节点,直接返回空
如果root的左右子树都不为空,这就比较麻烦,并且这时候新的搜索二叉树不唯一,我们选右子树的最小值作为新树的根节点的值
在这种情况下,我们先把右子树的最小值复制到root,然后可以这样想,我们可以把这种情况看做左子树为空右子树不为空的情况,
我们要进行的操作是递归操作中的删除右子树,只不过这时候的key值变成了我们选择的右子树的最小值了
至于右子树的最小值如何找到,那就是利用搜索树的性质,最小值在左子树上
*/
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null) return null;
if(root.val>key){
root.left = deleteNode(root.left, key);
return root;
}else if(root.val<key){
root.right = deleteNode(root.right, key);
return root;
}else{
if(root.left==null || root.right==null)
return root.left!=null ? root.left:root.right;
else{
TreeNode cur = root.right;
System.out.println("1");
while(cur.left!=null)
cur = cur.left;
root.val = cur.val;
root.right = deleteNode(root.right, cur.val);
return root;
}
}
}
}