从BST中移除一个节点是比较复杂的问题,需要分好几种情况讨论。
如这篇文章,就讨论了删除节点 1.有无左右子树 2.只有右子树 3.只有左子树 三种情况。
一种简单些的思维是只考虑删除节点是否有右子树(因为第一个比删除节点大的节点可能出现在右子树,不会出现在左子树)。
这里用Target表示删除节点,Parent表示删除节点的母节点。
1. 没有右子树
Parent.left / Parent.right = Target.left
2. 有右子树
1) 找到第一个比删除节点大的节点Node
2) 删除该节点Node
3) Target.val = Node.val 或 保留 Node 删除Target
/*** 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) {// write your code hereTreeNode dummy = new TreeNode(0);dummy.left = root;TreeNode parent = findNodeParent(dummy, root, value);TreeNode target;if (parent.left != null && parent.left.val == value) {target = parent.left;} else if (parent.right != null && parent.right.val == value) {target = parent.right;} else {return dummy.left;}deleteNode(parent, target);return dummy.left;}private TreeNode findNodeParent(TreeNode parent, TreeNode node, int val) {if (node == null || node.val == val) {return parent;}if (node.val < val) {return findNodeParent(node, node.right, val);} else {return findNodeParent(node, node.left, val);}}private void deleteNode(TreeNode parent, TreeNode target) {if (target.right == null) {if (parent.right == target) {parent.right = target.left;} else {parent.left = target.left;}} else {// Find first element that is greater than targetTreeNode node1 = target.right;TreeNode node2 = target;while (node1.left != null) {node2 = node1;node1 = node1.left;}// Remove node1if (node1 == node2.left) {node2.left = node1.right;} else {node2.right = node1.right;}// Remove targetif (target == parent.right) {parent.right = node1;} else {parent.left = node1;}node1.left = target.left;node1.right = target.right;}}
}