5

首先,我想说这不是家庭作业。我正在准备面试并遇到这个问题。我想我们可以传递中序水平序遍历的定义。:-)。

例如:

      50
   /      \
 10        60
/  \       /  \
5   20    55    70
        /     /  \
      51     65    80

上述树的中序和层序遍历为:

5、10、20、50、51、55、60、65、70、80

50, 10, 60, 5, 20, 55, 70, 51, 65, 80

我的想法:

(1) 遍历层序数组,找出出现在有序数组中的第一个元素。我们将此元素称为当前根。

(2) 在有序数组中找到当前根的索引。有序数组由索引分隔。有序数组的左边是当前根的左子树,有序数组的右边是当前根的右子树。

(3) 将有序数组更新为其左侧,然后转到步骤 1。

(4) 将有序数组更新为其右侧,然后转到步骤 2。

以上面的树为例。

(1) 5 is the first element appears in the in-order array. 

(2) [50 ...60] is the left sub-tree of 5 and [20 ... 80] is the right sub-tree of 5. 

(3) update the in-order array as [50 ... 60]

    (1) 10 is the first element appears in [50 10 60].

    (2) [50] is the left sub-tree of 10 and [60] is the right sub-tree of 10.

    (3) update ...

谁能帮我验证我的解决方案?如果再给一个,真的很感激。

4

4 回答 4

2

我认为你在正确的轨道上。下面是我使用您的数据制定的工作代码。

/*
//construct a bst using inorder & levelorder traversals.
//inorder    - 5, 10, 20, 50, 51, 55, 60, 65, 70, 80
//levelorder - 50, 10, 60, 5, 20, 55, 70, 51, 65, 80
         50
      /      \
    10        60
   /  \       /  \
  5   20    55    70
            /     /  \
          51     65    80
 */
struct node *construct_bst3(int inorder[], int levelorder[], int in_start, int in_end)
{
    static int levelindex = 0;
    struct node *nnode = create_node(levelorder[levelindex++]);

    if (in_start == in_end)
        return nnode;

    //else find the index of this node in inorder array. left of it is left subtree, right of this index is right.
    int in_index = search_arr(inorder, in_start, in_end, nnode->data);

    //using in_index from inorder array, constructing left & right subtrees.
    nnode->left  = construct_bst3(inorder, levelorder, in_start, in_index-1);
    nnode->right = construct_bst3(inorder, levelorder, in_index+1, in_end);

    return nnode;
}
于 2013-08-06T16:59:40.210 回答
0
    node *construct (in, s, e, level) 
    {
      while (level order has element)
      {
          make the root by taking the first element from level order
          find the index of root->Val in in order.

          segregate the elements of left subtree and right subtree (make sure while 
          segregating from level order the order of element should be same)  call them
          leftLevel[] and rightLevel[]

          construct tree by recursively calling
          root->left  = construct(inorder,s, index-1, leftLevel);
          root->right = construct(inorder, index+1, e, rightlevel);
          return root;
      }
 }

元素的分离将需要使用哈希表的 O(n),因此平衡树中的整体复杂度将为 O(nlogn),但当树不平衡时,它将变为 O(n^2)。

于 2014-09-25T00:56:21.250 回答
0

其实思路很简单,只要确定遍历顺序是否正确即可。比如你想做中序遍历,你可以简单的这么想:从左到右,从下到上。

  1. 遍历到左下(5),然后遍历到同一个节点的右(20)。

  2. 从底部 (10) 遍历到顶部 (50)。

  3. 在左边做同样的事情。

对于杠杆顺序,您可以从上到下,从左到右,一步一步地遍历。

于 2013-04-03T00:20:37.163 回答
0
            static tree MakeTreeFromInorderAndLevelOrder(int[] inorder,int[] lorder,int s,int n,int cnt1) {
    if(s>n || s>=inorder.length || n>=inorder.length || cnt1>=inorder.length) {
        return null;
    }
    int mIndex = Search(lorder[cnt1],inorder,s,n);
    tree t = new tree(lorder[cnt1]);

    cnt1 = 2*cnt1 + 1;
    t.left = MakeTreeFromInorderAndLevelOrder(inorder,lorder,s,mIndex-1,cnt1);
    //Boundary case
    if(cnt1<inorder.length && t.left==null) {
        t.right =   MakeTreeFromInorderAndLevelOrder(inorder,lorder,mIndex+1,n,cnt1);
    }
    else {
    cnt1 -=1;
    cnt1 /=2;
    cnt1 = 2*cnt1 + 2;
    t.right = MakeTreeFromInorderAndLevelOrder(inorder,lorder,mIndex+1,n,cnt1);
    //Boundary case
    if(t.right ==null && cnt1<inorder.length) {
        t.left = MakeTreeFromInorderAndLevelOrder(inorder,lorder,s,mIndex-1,cnt1);
    }
    }
    return t;
}
于 2014-02-15T16:03:33.187 回答