从有序和水平顺序遍历构造二叉树

时间:2013-02-13 15:36:51

标签: data-structures binary-tree inorder

首先,我想说这不是作业。我正在准备面试并遇到这个问题。我想我们可以通过in-orderlevel-order遍历的定义。 :-)。

例如:

      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)遍历level-order数组以找出第一个元素   它出现在有序数组中。我们将此元素称为当前元素   根

     

(2)在有序数组中找到当前根的索引。有序   数组由索引分隔。有序数组的左侧   是当前根的左子树和右侧的   in-order数组是当前根的右子树。

     

(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 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

实际上,这个想法很简单,你只需要确保遍历序列是正确的。例如,您想要进行有序遍历,您可以这样思考:从左到右,从下到上。

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

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

  3. 左边做同样的事情。

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

答案 2 :(得分: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;
}

答案 3 :(得分: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)。