Двоичное дерево из порядка и уровня обхода? - PullRequest
6 голосов
/ 01 января 2011

Можем ли мы доказать, что можно однозначно построить бинарное дерево из его обходов по порядку и по уровню?

Я думаю о доказательстве по индукции на нескольких уровнях.

Базовый вариант: деревья с 1 или 2 уровнями. Эти случаи понятны.

Предположим, что это верно для деревьев с l уровнями. То есть: можно однозначно построить двоичное дерево с l уровнями из его обходов по порядку и по порядку уровней.

Индуктивный случай: докажите, что это верно для деревьев с l + 1 уровнями. Не понятно, как поступить в этом случае. Любая помощь будет оценена.

Ответы [ 6 ]

6 голосов
/ 24 ноября 2012

Я дал этот урок в своем блоге а) - INORDER Traversal -POSTORDER Traversal

ИЛИ

b) -INORDER Обход -PREORDER Traversal

Обычно мы получаем такие вопросы, как: -

Создание дерева Binery из следующего обхода дерева

1)

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

ЗДЕСЬ самое важное, о чем ВСЕГДА помните: -

В ПРЕДЗАКАЗ ПЕРВЫЙ элемент - КОРЕНЬ дерева

В POSTorder LAST элемент корень дерева

Надеюсь, вы поняли: P

т.е. с учетом 1) Вопрос

1) Inorder: 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

H D B G перейдет на ПРАВИЛЬНУЮ ДЕРЕВО Root

Step 1)

Теперь, когда мы знаем, какой из них является Root, так что ...

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


Step 2)

Теперь для левой ветви дерева мы имеем 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

5 голосов
/ 25 января 2011

Не уверен насчет доказательства, но алгоритм для этого будет выглядеть следующим образом:

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

Чтобы доказать это, вы должны показать, что последовательность слева от корневого узла в обходе по порядкупрохождение по левому поддереву и то же самое для правого.Правда, но утомительно доказывать.

Вам также нужно показать, что порядок уровней поддерживается для поддеревьев.Также верно, но утомительно доказывать.

О да, возможно, вам придется доказать, что первый элемент в прохождении порядка уровней является корнем дерева, но это должно быть из определения.

1 голос
/ 11 декабря 2013

Этот код работает нормально без каких-либо сбоев во время выполнения. Извините за использование подхода Bruteforce. Код для printPretty () доступен по адресу
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;
}
1 голос
/ 06 августа 2013

Я думаю, что приведенный ниже код должен работать -

/*
//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;
}
0 голосов
/ 05 июля 2015

Java Solution:

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

}
0 голосов
/ 15 февраля 2014
    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;
}
...