2011-01-01 14 views
6

¿Podemos probar que se puede construir inequívocamente un árbol binario a partir de sus recorridos ordenados y de orden de nivel?Árbol binario de tramos de orden y de orden de nivel

Estoy pensando en una prueba por inducción en la cantidad de niveles.

Caso base: árboles con 1 o 2 niveles. Estos casos son claros.

Supongamos que esto se aplica a árboles con l niveles. Es decir: uno puede construir inequívocamente un árbol binario con l niveles de sus recorridos en orden y de orden de nivel.

Caja inductiva: demostrar que esto es válido para árboles con niveles de l + 1. No está claro cómo proceder en este caso. Cualquier ayuda será apreciada.

+0

Eh ... sólo curiosidad, es esta tarea? :) – Mehrdad

+0

Lo siento, tuve que mencionarlo antes. No, no es una tarea. Estoy tratando de resolver este http://stackoverflow.com/questions/4539698/finding-a-preorder-of-some-digits-with-their-levels-in-bst y estoy seguro, se puede resolver si tener una prueba de esto –

Respuesta

5

No estoy seguro de la prueba, pero la ALG para hacerlo sería a lo largo de las líneas,

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 

para demostrarlo que tendría que demostrar que la secuencia de la izquierda de un nodo raíz en un recorrido en orden es una inorden transversal del subárbol izquierdo, y luego lo mismo para la derecha. Es cierto, pero tedioso de probar.

También necesitaría mostrar que el orden de nivel se mantiene para los subárboles. También es cierto, pero tedioso de probar.

Oh, sí, puede que tengas que demostrar que el primer elemento en un cruce de orden de nivel es la raíz de un árbol, pero eso debería provenir de la definición.

+0

¿Puede explicar qué hace la función 'extract'? – SexyBeast

+0

La función de extracción necesita devolver la intersección de levelOrder y subIn, manteniendo el orden en levelOrder. –

5

he dado a este tutorial en mi blog a) - finde Transversal Transversal -POSTORDER

O

b) -INORDER Transversal Transversal -PREORDER

Normalmente nos Preguntas como: -

Crear árbol de la bodega del siguiente árbol Traversals

1)

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

AQUÍ el más importante creo recordar siempre es: -

En preordenPRIMERA elemento es raíz del árbol

En POSTorderLAST es el elemento raíz del árbol

espero que lo tienes: P

i.e considerando 1) Pregunta

1) finde: EACKFHDBG Preordenes: FAEKCDHGB

F es la raíz

eack irán a ÁRBOL secundario hacia la izquierda de la raíz

HDBG se ir a DERECHA SUB ÁRBOL de la raíz

Step 1) 

Ahora que sabemos cuál es la raíz Entonces ...

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


Step 2) 

Ahora para el árbol secundario hacia la izquierda tenemos eack de finde y AEKC mismas letras de Preordenes

es decir

Inorder E A C K 
Preorder A E K C 

ahora han encontrado A como Root nuevamente ahora árbol es

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


Step 3) 

Ahora letras son

Inorder C K 
Preorder K C 

Así que ahora árbol es

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

mismo procedimiento puede ser realizado en el árbol Sub derecho de la raíz F

Por orden posterior que tenemos que encontrar la raíz como el último elemento en transversal ....

versión de Colorfull o esto se puede ver aquí http://bloggerplugnplay.blogspot.in/2012/11/construction-of-binary-tree-from.html: P

1

Creo que el código de abajo debería funcionar -

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

Este código está trabajando muy bien sin ningún faults.Sorry tiempo de ejecución para utilizar el enfoque de fuerza bruta. El código para printPretty() está disponible en
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; 
} 
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; 
} 
+0

Esto funciona bien –

0

Solución de 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; 
} 

}