二叉树(五)

78 阅读2分钟

删除二叉搜索树中的节点

题目:450

  • 需要对二叉树结构进行修改

  • 递归三部曲,前两个容易

  • 返回值和参数:参考上一个插入节点的题,通过递归返回值删除节点

  • 结束条件:遇空节点返回

  • 单层递归逻辑:

  • 根据二叉搜素树的性质找被删除节点在的位置

  • 主要是要考虑到以下五种情况

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了

  • 找到删除的节点

    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
       TreeNode cur = root.right;
        while (cur.left != null) {
          cur = cur.left;
        }
        cur.left = root.left;
        root = root.right;
        return root;

修剪二叉搜索树

题目:669

  • 单层逻辑上面,不用想的那么复杂,例如我们发现节点root并不符合区间要求,就去继续找符合条件的节点,根据root.val是太少还是太多,选择新的递归范围是root.left 还是 root.right

  • 这个方法的单看下来,好像就是返回在区间范围内的节点,毕竟不在区间范围内的,都被拖去去找它那可能在区间内的节点了

  • 如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。

      if (root.val < low) {
          return trimBST(root.right, low, high);//寻找在区间内的节点
      }
    
  • 如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。

将有序数组转为二叉搜索树

题目:108

  • 因为已经是升序了,还要保持高度差,所以直接每次就取“当前数组”的nums[mid]为中,然后mid左边做左子树,mid右边做右子树,不断递归

  • 递归返回值和参数:

    public TreeNode makeTree(int[] nums, int left, int right)

  • 终止条件:无节点可创造

        if (left > right) {
            return null;
        }
  • 单层递归逻辑:
        int mid = (left + right) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = makeTree(nums, left, mid - 1);
        root.right = makeTree(nums, mid + 1, right);
        return root;

把二叉搜索树转换为累加树

题目:538

  • 感觉是一款顺序为右中左
  • 不需要递归函数的返回值,遍历一下整个树就行
public void convertBST1(TreeNode root)
  • 需要有一个全局变量pre来保存此前累加的值(比当前节点值大的节点值和)
  • 那么就按照平时递归遍历来就行,只不过把中节点的操作更新为了“更新节点值”和“更新累加值pre”
        convertBST1(root.right);
        sum += root.val;
        root.val = sum;
        convertBST1(root.left);