【问题标题】:How to check if a given array represents postorder traversal of Binary Search Tree?如何检查给定数组是否代表二叉搜索树的后序遍历?
【发布时间】:2017-01-10 11:58:19
【问题描述】:

有一个给定的数组,我们需要知道它是否代表 BST 的后序遍历。 (例如:如果问题是 in-order 而不是 post-order ,我们只需要检查数组是否排序时间 o(n))

【问题讨论】:

  • 听起来像是一个有趣的家庭作业问题。你在尝试解决这个问题时有什么想法?
  • 它几乎可以代表任何东西(例如:我妈妈最喜欢的彩票号码)...请澄清问题。
  • @KarolyHorvath 通过“代表”我认为 OP 基本上意味着“是”。是否可以通过从二叉搜索树开始,进行后序遍历,并按照访问的顺序将节点处的值填充到数组中的元素来获得数组?我认为这个问题很清楚,但没有显示出任何研究工作。
  • 如果我们在任何 BST 上进行后序遍历,并且我们得到表示 BST 的数组,但它也可以表示任何其他树,但至少一棵树必须是所有 BST可以呈现的树。
  • @m.zmiro:这就是我的意思,谢谢...解决了歧义。

标签: arrays algorithm data-structures binary-search-tree tree-traversal


【解决方案1】:

使用以下代码可以估计给定数组是否可能表示 BST。

程序:

       10
      /  \
     7   12
    / \    \
   6   9    31
           /
          14

设数组为 arr={6,9,7,14,31,12,10}

现在我们开始从末尾遍历数组,直到到达元素小于 end_index (arr[end_index]=10) 的索引。然后我们将该索引存储在 temp 中。 (这里 temp=2 即 arr[temp]=7 as 7

逻辑:

后序是指{{LEFT elements},{RIGHT elements},{ROOT}}。 因此数组的顺序应该是{(小于父元素的元素),(大于父元素的元素),(父元素)}

这是我们在遍历数组时要确保的。

代码如下:

public class ckeckIfPostOrderAbinaryTree {

    public static void main(String[] args) {

        int[] arr={6,9,7,14,31,12,10};
        System.out.println(solve(arr,0,arr.length-1));

    }
    public static boolean solve(int[] arr,int strt,int end){
        if(strt>=end){
            return true;
        }

        int x=arr[end],index=end-1;
        while(index>=strt && arr[index]>x){
            index--;
        }
        int temp=index;
        while(index>=strt){
            if(arr[index]>x){
                return false;
            }
            index--;
        }
        if(temp==strt){
            return solve(arr,strt,end-1);
        }
        else{
        return (solve(arr,strt,temp) && solve(arr,temp+1,end-1));
        }
    }

}

【讨论】:

  • 如果我们假设给定数组中没有重复项,此解决方案效果很好,但它不适用于像 {1,1,1,1,1,1} 这样的数组。所以我建议你把这行代码从第二个while循环块中的if(arr[index]>x)改成if(arr[index]>=x),让这个解决方案效果更好。
【解决方案2】:

后序遍历由 {LEFT Subtree}{Right Subtree}{ROOT} 完成。因此这里的想法是从右端开始遍历数组。数组中的最后一个元素是根,从右到左,当你遇到较小的元素时,标记边界从左子树开始,BST 不会有来自这个索引的更大元素,这适用于每个子树. C++ 中的算法是这样的 -

bool isBST(int arr[], int n){

//Set root to the max integer value.
int root = INT_MAX;

//Stack used to keep track of current subtree
std::stack<int>s;

//Start at the end of the array because Postorder traversal is
// <L><R><D>
for (int i = n-1; i>=0; i--) {
    //False if any larger number in the left subtree
    if (arr[i]> root) {
        return false;
    }

    //Reset the root for boundary of every subtree,
    //when current item is smaller than top,
    //that means we are starting with left subtree of this root
    while (!s.empty() &&  arr[i] < s.top()) {
        root = s.top();
        s.pop();
    }
    //Keep pushing the elements otherwise
    s.push(arr[i]);
  }
  return true;

}

【讨论】:

  • 这是正确的解决方案。不知道为什么没有赞成票。
  • 这是 O(n) 复杂度的最优解,使用单调递减堆栈。
【解决方案3】:

快速健全性检查:如果数组中的最后一项不是根节点,则它不是后序遍历的结果。类似地,如果进行了前序遍历,则数组中的第一项是根。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多