给定一棵具有不同节点值的二叉查找树,删除树中与给定值相同的节点。如果树中没有相同值的节点,就不做任何处理。你应该保证处理之后的树仍是二叉查找树。
样例
给出如下二叉查找树:
5
/ \
3 6
/ \
2 4
删除节点3之后,你可以返回:
5
/ \
2 6
\
4
或者:
5
/ \
4 6
/
2
解题思路:
首先通过递归写出限制条件,即先通过value值与root.val对比找到对应的待删除节点。
然后分情况讨论,若待删除节点只有一个孩子节点,直接将孩子树连上即可
若待删除节点d左右都有孩子节点,则
找到节点s = min(d.right),s是d的后继
s.right = delMin(d.right)
s.left = d.left
删除d
s则是新的子树的根
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: The root of the binary search tree.
* @param value: Remove the node with given value.
* @return: The root of the binary search tree after removal.
*/
public TreeNode removeNode(TreeNode root, int value) {
if(root == null)
return null;
//value大于root.val,向右搜索
if(value > root.val){
root.right = removeNode(root.right, value);
return root;
}
//value小于root.val,向左搜索
if(value < root.val){
root.left = removeNode(root.left, value);
return root;
}
//value == root.value
//当待删除节点仅有右节点时
if(root.left == null){
TreeNode node = root.right;
root.right = null;
return node;
}
//当待删除节点仅有左节点时
if(root.right == null){
TreeNode node = root.left;
root.left = null;
return node;
}
//当待删除节点有两个节点时
//root.left != null && root.right != null
TreeNode s = minimum(root.right);
s.right = removeMin(root.right);
s.left = root.left;
root.left = root.right = null;
return s;
}
//找出以root为根子树的最小节点
private TreeNode minimum(TreeNode root){
if(root == null)
return null;
if(root.left == null)
return root;
return minimum(root.left);
}
//删除以root为根子树的最小节点,返回根节点
private TreeNode removeMin(TreeNode root){
if(root == null)
return null;
if(root.left == null){
TreeNode node = root.right;
root.right = null;
return node;
}
root.left = removeMin(root.left);
return root;
}
}