📜  从给定的后序构造一个二叉搜索树(1)

📅  最后修改于: 2023-12-03 14:49:27.802000             🧑  作者: Mango

从给定的后序构造一个二叉搜索树

二叉搜索树(Binary Search Tree,简称BST)是一种排序二叉树,其中每个节点都含有一个键(key)和一个值(value),并且节点的键是唯一的。BST的左子树只包含键小于节点键的节点,右子树只包含键大于节点键的节点。因为BST具有这些特性,所以BST可以进行快速的查找、插入、删除操作。

在BST中,我们可以根据先序遍历、中序遍历或后序遍历构造出唯一的BST。本文将介绍如何从给定的后序遍历构造出一个BST。

算法

从给定的后序遍历数组中,最后一个元素是根节点。我们可以把数组分成两部分:左子树的节点和右子树的节点。对于左子树,所有节点的键都小于根节点的键;对于右子树,所有节点的键都大于根节点的键。

然后我们可以递归的构建左右子树,直到子树中只剩下一个节点。

具体的构造方法如下:

  • 如果当前子树为空,返回null。
  • 取出数组最后一个元素作为根节点。
  • 从后序遍历数组中,寻找第一个小于根节点的元素,它的下标记为i。i左侧的所有元素构成根节点的左子树,右侧的所有元素构成根节点的右子树。
  • 分别递归计算左子树和右子树,得到左子树的根节点left和右子树的根节点right。
  • 将根节点的左指针指向left,右指针指向right,然后返回根节点。
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public TreeNode buildTree(int[] inorder, int[] postorder) {
    if (postorder.length == 0) {
        return null;
    }
    int n = postorder.length;
    int rootVal = postorder[n - 1];
    TreeNode root = new TreeNode(rootVal);
    int i = 0;
    while (i < n && inorder[i] != rootVal) {
        i++;
    }
    int[] leftInorder = Arrays.copyOfRange(inorder, 0, i);
    int[] rightInorder = Arrays.copyOfRange(inorder, i + 1, n);
    int[] leftPostorder = Arrays.copyOfRange(postorder, 0, i);
    int[] rightPostorder = Arrays.copyOfRange(postorder, i, n - 1);
    root.left = buildTree(leftInorder, leftPostorder);
    root.right = buildTree(rightInorder, rightPostorder);
    return root;
}
复杂度分析
  • 时间复杂度:每次递归都将数组分成两部分,因此递归深度为树的高度h,每次递归需要O(n)的时间复杂度,因此总时间复杂度为O(nh);由于树的高度h最坏为n,因此总时间复杂度为O(n^2)。但是,如果我们在递归的过程中使用哈希表来存储中序遍历数组每个元素对应的下标,我们可以在O(1)的时间内找到根节点在中序遍历数组中的下标,这样总时间复杂度就可以降为O(nlogn)。
  • 空间复杂度:每次递归都要新建O(1)个树节点,递归深度为树的高度h,因此总空间复杂度为O(h),最坏情况下h=n,因此总空间复杂度为O(n)。
总结

本文介绍了如何从给定的后序遍历数组构造一个二叉搜索树。我们使用了递归的方法进行构造,在每次递归中,我们寻找根节点、划分子数组、递归计算左右子树并连接根节点、左子树和右子树。这样就可以得到一个BST。