Data structures 从按序和按级遍历构造二叉树

Data structures 从按序和按级遍历构造二叉树,data-structures,binary-tree,inorder,Data Structures,Binary Tree,Inorder,首先,我想声明这不是家庭作业。我正在准备面试,遇到了这个问题。我想我们可以通过和遍历的定义。:- 例如: 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)

首先,我想声明这不是家庭作业。我正在准备面试,遇到了这个问题。我想我们可以通过和遍历的定义。:-

例如:

      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) 遍历levelorder数组以找出第一个元素 它出现在顺序数组中。我们称这个元素为current 根

(2) 在顺序数组中查找当前根的索引。秩序井然 数组由索引分隔。顺序数组的左侧 是当前根目录的左子树和 顺序数组是当前根的右子树

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

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

以上面的树为例

有人能帮我验证我的解决方案吗?
如果再给你一个,你会非常感激。

事实上,这个想法很简单,你只需要确保遍历序列正确与否。例如,你想按顺序遍历,你可以简单地这样想:从左到右,从下到上

  • 移动到左下角(5),然后移动到同一节点的右下角(20)

  • 从底部(10)移动到顶部(50)

  • 在左边做同样的事情


  • 按照杠杆顺序,你可以从上到下,从左到右,一步一步地移动。

    我想你走对了。下面是我使用您的数据编制的工作代码

    /*
    //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;
    }
    
    静态树maketreefrominorder和levelorder(int[]inorder,int[]lorder,int s,int n,int cnt1){
    如果(s>n | | s>=inorder.length | | n>=inorder.length | | cnt1>=inorder.length){
    返回null;
    }
    int mIndex=搜索(领主[cnt1],顺序,s,n);
    树t=新树(主[cnt1]);
    cnt1=2*cnt1+1;
    t、 左=maketreefrominorder和levelorder(inorder、lorder、s、mIndex-1、cnt1);
    //边界情况
    如果(cnt1
    
    元素的分离将需要使用哈希表的O(n),因此在平衡树中的总体复杂性将是O(nlogn),但它将变成O(n^2)当树不平衡时。

    我认为这不符合顺序。我只是编写了一个程序来验证它。顺序遍历似乎没有问题。您能为示例树提供顺序遍历,让我再次检查一下吗?似乎我错了。这看起来是正确的,抱歉。您好,欢迎来到stackoverflow!但是,我知道我不明白这是怎么回答这个问题的。海报问是否有人可以验证他的算法的正确性,而不是一个实现。如果你认为你的实现以某种方式提供了这种验证,请在你的答案中解释。另外,请确保你的答案格式正确,可读性好。什么是时空比较这个算法的存在性?O(n)?@AnV它不可能是O(n)。它可能是O(logn)的某个因子。我们需要为数组中的所有n个元素创建节点,然后在返回时将它们附加到它们的父元素。所以我认为TC应该是O(n)。你能解释一下它是如何成为O(logn)的因子的吗?@AnV抱歉!不知道我写上述评论时在想什么。上述方法的时间复杂度上限为O(n3)。我们在搜索中进行线性扫描,然后进行左、右子树。如果我们在搜索中使用查找表,我们可以得到O(n2)
    /*
    //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;
    }
    
                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;
    }
    
        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;
          }
     }