来自有序和水平顺序遍历的二叉树?

时间:2011-01-01 20:52:20

标签: algorithm binary-tree

我们能证明一个人可以从其有序和水平顺序遍历中明确地构造二叉树吗?

我正在考虑一个关于级别数量的归纳证据。

基本案例:1或2级别的树木。这些案件很清楚。

假设这适用于具有l级别的树。也就是说:可以从其有序和水平顺序遍历中明确地构造一个具有l级别的二叉树。

归纳案例:证明这适用于l + 1级别的树木。在这种情况下不清楚如何进行。任何帮助将不胜感激。

6 个答案:

答案 0 :(得分:6)

我在我的博客上给了这个教程a) - INORDER Traversal -POSTORDER Traversal

OR

b)-INORDER Traversal     -PREORDER Traversal

我们通常会收到如下问题: -

从以下树遍历

创建Binery树

1)

Inorder:   E  A  C  K  F  H  D  B  G
Preorder:  F  A  E  K  C  D  H  G  B

这里最重要的想法总是记得: -

  

预订 FIRST 元素是树的根

     

POSTorder 最后元素是树的ROOT

我希望你明白了:P

即考虑1)问题

1)按顺序:E A C K F H D B G.     预购:F A E K C D H G B

F 是root

E A C K 将转到Root的LEFT SUB TREE

H D B G 将转到Root的右子树

Step 1)

现在我们知道哪一个是Root So ...

                     F
                   /  \
        ( E A C K)      (H D B G) 


Step 2)

现在我们有LEFT SUB TREE 来自预订的E A C K和来自预购的相同字母A E K C

 Inorder   E A C K
 Preorder A E K C

现在再次找到 A 作为Root,现在树

                     F
                   /   \
                  A      (H D B G) 
                /  \
               E    (C K)


Step 3)

现在信件

Inorder   C K
Preorder  K C

所以现在树

                           F
                         /   \
                        A     (H D B G) 
                      /  \
                     E    K
                         /
                        C

可以在根F的右子树上完成相同的过程

对于Postorder,我们必须找到Root作为遍历中的最后一个元素....

在这里可以看到Colorfull版本或http://bloggerplugnplay.blogspot.in/2012/11/construction-of-binary-tree-from.html:P

答案 1 :(得分:5)

不确定证据,但这样做的alg就是这样,

f(inorder, levelorder):
      if length(levelorder) == 0:
          return None
      root = levelorder[0]#set root to first element in levelorder
      subIn1, subIn2 = partition(inorder, levelorder[0]) #partition inorder based on root
      subLevel1 = extract(levelOrder, subIn1)#remove elements in level order not in subIn1
      subLevel2 = extract(levelOrder, subIn2)#remove elements in level order not in subIn2
      root->left = f(subIn1, subLevel1)
      root->right = f(subIn2, subLevel2)
      return root

为了证明这一点,你必须证明inorder遍历中根节点的左边序列是左子树的inorder遍历,然后是右边的相同遍历。没错,但要证明这很乏味。

您还需要显示为子树维护的levelorder。同样正确,但要证明是乏味的。

哦,是的,您可能必须证明级别顺序遍历中的第一个元素是树的根,但这应该来自定义。

答案 2 :(得分:1)

我认为以下代码应该有效 -

/*
//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;
}

答案 3 :(得分:1)

此代码工作正常,没有任何运行时错误。请使用Brute Force方法。 打印Pretty()的代码可在以下处获得 http://leetcode.com/2010/09/how-to-pretty-print-binary-tree.html

#include <fstream>
#include <iostream>
#include <deque>
#include <iomanip>
#include <sstream>
#include <string>

#include <math.h>   
#include <string.h>
using namespace std;

struct BinaryTree {

  BinaryTree *left, *right;
  char data;
  BinaryTree(int val) : left(NULL), right(NULL), data(val) { }
  ~BinaryTree(){ this->left = NULL; this->right = NULL ;  }

};
BinaryTree *createNode(char d)
{
    return new BinaryTree(d);
}
#define MAX     256
int indexOf[MAX];

void inorderIndex(char *IN,int n)
{
    int i=0;
    for (i = 0; i < n; i++)
    {
        indexOf[ (int)IN[i] ] = i;
    }
    return;
}

int searchIndex(char arr[], int strt, int end, char value)
{
    int i;
    for(i = strt; i <= end; i++)
        if(arr[i] == value)
          return i;
    return -1;
}

BinaryTree *INLEVEL(char *in,char *level,int in_st,int in_end,int lev_st,int lev_end)
{

    int idx=-1,i,left_lev_idx=-1,right_lev_idx=-1;
    if(level[lev_st] == '\0' )
        return NULL;

    idx = searchIndex(in,in_st,in_end,level[lev_st] );
    if(idx == -1)
        return NULL;

    BinaryTree*root=createNode( level[lev_st] );
//  root->data = level[st];
    root->left = root->right = NULL;

    for ( i = lev_st+1; i <= lev_end ; i++)
    {
        if ( (indexOf[ (int) level[i] ] > idx) && (indexOf[ (int) level[i] ] <= in_end ) )
            if(right_lev_idx == -1)
                right_lev_idx = i;

        if ( (indexOf[ (int) level[i] ] < idx) && (indexOf[ (int) level[i] ] >= in_st ) )
            if(left_lev_idx == -1)
                left_lev_idx = i;

    }
    if(left_lev_idx != -1)
        root->left = INLEVEL(in,level,in_st,idx-1,left_lev_idx,lev_end);

    if(right_lev_idx != -1)
        root->right = INLEVEL(in,level,idx+1,in_end,right_lev_idx,lev_end);

    return root;
}

int main() 
{
     char IN[100] ="DBFEAGCLJHK"
    ,LEVEL[100]="ABCDEGHFJKL";
    BinaryTree *root =(BinaryTree *) NULL;
    inorderIndex(IN,strlen(IN) );
    root=INLEVEL(IN,LEVEL,0,strlen(IN)-1,0,strlen(IN)-1 );
//      printPretty(root, 2, 0, cout);      


    return 0;
}

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

答案 5 :(得分:0)

Java解决方案:

import java.util.HashMap;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class InorderLevelorder {

private static int[] levelArray;

public static void main(String[] args) {

    //in order traversal of binary tree
    int[] in = {4,10,3,1,7,11,8,2};

    //level order traversal of binary tree
    int[] lev = {7,10,2,4,3,8,1,11};

    //Builds a Binary Tree and returns the root node
    buildTree(in, lev);
}

private static BinaryTreeNode buildTree(int[] in, int[] lev){

    //Hash the values of both the arrays for O(1) time search
    HashMap<Integer, Integer> inMap = new HashMap<Integer, Integer>();
    HashMap<Integer, Integer> levMap = new HashMap<Integer, Integer>();
    levelArray = lev;
    for(int i=0;i<in.length;i++)
        inMap.put(in[i], i);
    for(int j=0;j<lev.length;j++)
        levMap.put(lev[j], j);
    return buildTree(in, lev, 0, in.length - 1, inMap, levMap);
}

//recursive method that constructs the binary tree
private static BinaryTreeNode buildTree(int[] in, int[] lev, int inStart, int inEnd, HashMap<Integer, Integer> inMap, HashMap<Integer, Integer> levMap){

    if(inStart > inEnd)
        return null;

    int nodeVal = lev[0];
    BinaryTreeNode node = new BinaryTreeNode();
    node.setData(nodeVal);

    if(inStart == inEnd)
        return node;

    int inIndex = inMap.get(nodeVal);
    int[] leftSubTree = subArray(in, levelArray, inStart, inIndex-1, inMap, levMap);
    int[] rightSubTree = subArray(in, levelArray, inIndex+1, inEnd, inMap, levMap);

    node.setLeftNode(buildTree(in, leftSubTree, inStart, inIndex-1, inMap, levMap));
    node.setRightNode(buildTree(in, rightSubTree, inIndex+1, inEnd, inMap, levMap));

    return node;
}

private static int[] subArray(int[] in, int[] lev, int inStart, int inEnd, HashMap<Integer, Integer> inMap, HashMap<Integer, Integer> levMap){

    int[] newSubArray = new int[inEnd - inStart + 1];
    SortedSet<Integer> set = new TreeSet<Integer>();
    for(int i=inStart;i<=inEnd;i++){
        int levIndex = levMap.get(in[i]);
        set.add(levIndex);
    }
    int j=0;
    Iterator<Integer> iter = set.iterator();
    while(iter.hasNext()){
        int levIndex = iter.next();
        int levValue = lev[levIndex];
        newSubArray[j] = levValue;
        j++;
    }

    return newSubArray;
}
}

class BinaryTreeNode {

private int data;
private BinaryTreeNode leftNode;
private BinaryTreeNode rightNode;

public int getData() {
    return data;
}
public void setData(int data) {
    this.data = data;
}
public BinaryTreeNode getLeftNode() {
    return leftNode;
}
public void setLeftNode(BinaryTreeNode leftNode) {
    this.leftNode = leftNode;
}
public BinaryTreeNode getRightNode() {
    return rightNode;
}
public void setRightNode(BinaryTreeNode rightNode) {
    this.rightNode = rightNode;
}

}