给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (root.val < key) {
root.right = deleteNode(root.right, key);
return root;
}
if (root.val > key) {
root.left = deleteNode(root.left, key);
return root;
}
//root.val==key的情况
if (root.left==null){
TreeNode ret = root.right;
root.right = null;
return ret;
}
if (root.right==null){
TreeNode ret = root.left;
root.left = null;
return ret;
}
//root的左右都不为空的情况
//得到root的前驱, 即左子树的最大值
TreeNode pre =max(root.left);
//前驱的左孩子为root的左子树删除最大值后返回的根节点
pre.left = removeMax(root.left);
pre.right = root.right;
root.left = root.right = null;
return pre;
}
//得到以root为根的树的最大节点
private TreeNode max(TreeNode root) {
if (root==null){
return null;
}
while (root.right!=null){
root = root.right;
}
return root;
}
//删除以root为根的BST的最大节点,返回新的根节点
private TreeNode removeMax(TreeNode root) {
if (root==null){
return null;
}
if (root.right==null){
TreeNode left = root.left;
root.left = null;
return left;
}else {
root.right = removeMax(root.right);
return root;
}
}