二叉搜索树的节点删除
二叉搜索树的删除相对于添加要难的多,需要考五种情况
-
树中不存在要删除的元素
-
删除节点没有左右孩子节点,直接删除
-
删除节点只有右孩子,没有左孩子,把右孩子接在根节点上
-
删除节点只有左孩子,没有右孩子,把左孩子接在根节点上
-
删除节点左右都有孩子,把左孩子放在右孩子的最左边节点上,然后用右孩子替换根节点
class Solution { public TreeNode deleteNode(TreeNode root, int key) { return delete(root, key); } public TreeNode delete(TreeNode root, int key) { //第一种情况,没有找到要删除的节点 if (root == null) { return null; } //树中有要删除节点,找到节点key == root.val if (root.val == key) { //第二种情况,节点没有左右孩子,直接删除 if (root.left == null && root.right == null) return null; //第三种情况,节点有右孩子,没有左孩子 if (root.left == null) return root.right; //第四种情况,节点有左孩子,没有右孩子 if (root.right == null) return root.left; //第五种情况,节点左右都有孩子,则右孩子替换被删除节点,左孩子放在右孩子的最左侧节点处 TreeNode cur = root.right; while (cur.left != null) { cur = cur.left; } cur.left = root.left; root = root.right; return root; } if (key > root.val) root.right = delete(root.right, key); if (key < root.val) root.left = delete(root.left, key); return root; } }
类似题目
看过删除二叉搜索树中节点这道题后,想当然的就认为,本体只需要对二叉搜索树树进行遍历,遇到不在范围内的节点,直接调用删除二叉搜索树中指定节点的方法,就可以了。
这么想当然没错,但是本题可以有更简单的解题思路:利用好二叉搜索树的特性
-
当前节点如果小于指定范围,则其左子树的所有节点一定也小于指定范围。则删除的时候,只用当作节点只有右孩子的情况删除该节点即可(连带着左子树一起删除)
-
当前节点如果大于指定范围,则其右子树的所有节点一定也小于指定范围。则删除的时候,只用当作节点只有左孩子的情况删除该节点即可(连带着右子树一起删除)
所以直接先序遍历,然后找到不在范围的节点,按照上面两个规则进行删除即可
如图所示,范围为:[2,7],则遍历到1的时候,可以将1和其左子树一起扔掉,让2接到3的左子树,再递归进行判断,右子树同理。
-
确定递归函数饿返回值和参数
public TreeNode trimBST(TreeNode root, int low, int high)
-
确定递归边界
if(root == null) return root;
-
写递归体
if(root.val < low) { return trimBST(root.right, low,high);//将该节点的右孩子返回(删掉该节点和其左孩子) } if(root.val > low) { return trimBST(root.left, low,high);//将该节点的左孩子返回(删掉该节点和其右孩子) } root.left = trimBST(root.left, low, high);//用来接左孩子的返回值,这样return trimBST(root.right, low,high);的返回值才有意义 root.right = trimBST(root.right, low, high);//同理
class Solution { public TreeNode trimBST(TreeNode root, int low, int high) { if(root == null) return root; if(root.val < low) { return trimBST(root.right, low, high); } if (root.val > high) { return trimBST(root.left, low, high); } root.left = trimBST(root.left,low,high); root.right = trimBST(root.right,low,high); return root; } }