주어진 Inorder 및 Preorder Traversals에서 이진 트리 생성


난이도 중급
자주 묻는 질문 아마존 Apple 블룸버그 ByteDance 페이스북 서비스 구글 Microsoft 신탁
이진 트리 깊이 우선 검색 나무

이 문제에서 우리는 이진 트리. 주어진 Inorder 및 Preorder 순회에서 이진 트리를 구성해야합니다.

Input:

Inorder= [D, B, E, A, F, C]

Preorder= [A, B, D, E, C, F]

Output:

Pre-order traversal of the tree formed by the given preorder and inorder A B D E C F

In-order traversal of the tree formed by the given preorder and inorder D B E A F C

Post-order traversal of the tree formed by the given preorder and inorder D E B F C A

선주문 순회

사전 주문 순회에서는 먼저 루트 노드를 인쇄합니다. 그런 다음 존재하는 경우 왼쪽 하위 트리를 횡단합니다. 그리고 마지막으로 오른쪽 하위 트리가있는 경우 횡단합니다.

( 순회 모든 노드에 대해 동일한 방식으로 수행됨)

순서 순회

Inorder traversal에서는 노드의 왼쪽 하위 트리가있는 경우 먼저 탐색합니다. 그런 다음 루트 노드를 인쇄하십시오. 마지막으로, 존재한다면 오른쪽 하위 트리를 통과하십시오.

(순회는 모든 노드에 대해 동일한 방식으로 수행됩니다)

  1. 따라서 사전 주문 순회가있는 경우 항상 0th 인덱스 요소는 트리의 루트 노드를 나타냅니다.
  2. 그리고 우리가 inorder traversal을 가지고 있다면 모든 i 번째 인덱스에 대해 왼쪽에있는 모든 요소는 왼쪽 하위 트리에 있고 오른쪽에있는 모든 요소는 오른쪽 하위 트리에 있습니다.

위의 두 속성을 사용하여 주어진 순회로 트리를 구성 할 수 있습니다.

이진 트리 생성을위한 알고리즘

  1. 사전 주문 순회에서 다음 요소를 선택합니다 (인덱스 0으로 선택 시작).
  2. 선택한 요소로 데이터를 사용하여 새 노드를 만듭니다.
  3. hashMaps를 사용하여 Inorder traversal에서 선택한 요소의 인덱스를 찾아 인덱스를 찾는 데 걸리는 시간을 줄입니다.
  4. 선택한 요소의 왼쪽에있는 요소에 대해 동일한 함수를 재귀 적으로 호출하고 선택한 노드의 왼쪽에 할당합니다.
  5. 선택한 요소의 오른쪽에있는 요소에 대해 동일한 함수를 재귀 적으로 호출하고 선택한 노드의 오른쪽에 할당합니다.
  6. 루트 노드를 반환합니다.

예를 들어 이해합시다

순서 = [D, B, E, A, F, C]

선주문 = [A, B, D, E, C, F]

1: 선택한 요소는 A입니다.

주어진 Inorder 및 Preorder Traversals에서 이진 트리 생성

2: 선택한 요소는 B입니다.

주어진 Inorder 및 Preorder Traversals에서 이진 트리 생성

3: 선택한 요소는 D입니다.

주어진 Inorder 및 Preorder Traversals에서 이진 트리 생성

4: 선택한 요소는 E입니다.

주어진 Inorder 및 Preorder Traversals에서 이진 트리 생성

5: 선택한 요소는 C입니다.

6: 선택한 요소는 F입니다.

실시

이진 트리 생성을위한 C ++ 프로그램

#include<bits/stdc++.h>
using namespace std;
struct node{
    char data;
    node* left;
    node* right;
    
    //constructor
    node(char data){
        this->data = data;
        left = right = NULL;
    }
};

//Function to print pre-order of binary tree
void preorder(node* root){
    if(root!=NULL){
        cout<<root->data<<" ";
        preorder(root->left);
        preorder(root->right);
    }
}
//Function to print in-order of binary tree
void inorder(node* root){
    if(root!=NULL){
        inorder(root->left);
        cout<<root->data<<" ";
        inorder(root->right);
    }
}

//Function to print post-order of binary tree
void postorder(node* root){
    if(root!=NULL){
        postorder(root->left);
        postorder(root->right);
        cout<<root->data<<" ";
    }
}

//Function to construct binary tree from it's preorder and inorder traversal
node* buildTree(char in[], char pre[], int start, int end, unordered_map<char, int>& m, int& index){
    //base case
    if(start>end){
        return NULL;
    }
    
    char current = pre[index++];
    node* p = new node(current);
    int inFind = m[current];
    p->left = buildTree(in, pre, start, inFind-1, m, index);
    p->right = buildTree(in, pre, inFind+1, end, m, index);
    return p;
}
int main(){
    int n;
    cin>>n;
    char in[n],pre[n];
    for(int i=0;i<n;i++){
        cin>>in[i];
    }
    for(int i=0;i<n;i++){
        cin>>pre[i];
    }
    
    //make hashmap to find the node in inorder
    unordered_map<char,int> m;
    for(int i=0;i<n;i++){
        m[in[i]] = i;
    }
    int start = 0,end = n-1, index = 0;
    node* root = buildTree(in, pre, start, end, m, index);
    cout<<"Pre-order traversal of the tree formed by the given preorder and inorder ";
    preorder(root);
    cout<<endl;
    cout<<"In-order traversal of the tree formed by the given preorder and inorder ";
    inorder(root);
    cout<<endl;
    cout<<"Post-order traversal of the tree formed by the given preorder and inorder ";
    postorder(root);
    cout<<endl;
}
6
D B E A F C
A B D E C F
Pre-order traversal of the tree formed by the given preorder and inorder A B D E C F 
In-order traversal of the tree formed by the given preorder and inorder D B E A F C 
Post-order traversal of the tree formed by the given preorder and inorder D E B F C A 

이진 트리 생성을위한 JAVA 프로그램

import java.util.*; 

public class Main { 
    public static class node { 
    	char data; 
    	node left; 
    	node right; 
    	//constructor
    	node(char x) { data = x; } 
    };
    static int index=0;
    
    //Function to construct binary tree from it's preorder and inorder traversal
  public static node buildTree(char in[], char pre[], int start, int end, Map<Character, Integer> m) 
  { 
          //base case
        if(start>end){
            return null;
        }
        
        char current = pre[index++];
        node p = new node(current);
        
        //leaf node
        if(start == end){
            return p;
        }
        int inFind = m.get(current);
        p.left = buildTree(in, pre, start, inFind-1, m);
        p.right = buildTree(in, pre, inFind+1, end, m);
        return p;
  } 

  //Function to print pre-order of binary tree
    public static void preorder(node root){
        if(root!=null){
            System.out.print(root.data+" ");
            preorder(root.left);
            preorder(root.right);
        }
    }
    //Function to print in-order of binary tree
    public static void inorder(node root){
        if(root!=null){
            inorder(root.left);
            System.out.print(root.data+" ");
            inorder(root.right);
        }
    }
    
    //Function to print post-order of binary tree
    public static void postorder(node root){
        if(root!=null){
            postorder(root.left);
            postorder(root.right);
            System.out.print(root.data+" ");
        }
    }

  public static void main(String args[]) 
  { 
    Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        char[] in = new char[n],pre = new char[n];
        for(int i=0;i<n;i++){
            in[i] = sc.next().charAt(0);
        }
        for(int i=0;i<n;i++){
            pre[i] = sc.next().charAt(0);
        }
        
        //make hashmap to find the node in inorder
        Map<Character, Integer> m=new HashMap<Character, Integer>();   
        for(int i=0;i<n;i++){
            m.put(in[i], i);
        }
        int start = 0,end = n-1;
        node root = buildTree(in, pre, start, end, m);
        System.out.print("Pre-order traversal of the tree formed by the given preorder and inorder ");
        preorder(root);
        System.out.print("\n");
        System.out.print("In-order traversal of the tree formed by the given preorder and inorder ");
        inorder(root);
        System.out.print("\n");
        System.out.print("Post-order traversal of the tree formed by the given preorder and inorder ");
        postorder(root);
        System.out.print("\n");
    }
}

8
D B E A F C G H
A B D E C F H G
Pre-order traversal of the tree formed by the given preorder and inorder A B D E C F H G 
In-order traversal of the tree formed by the given preorder and inorder D B E A F C G H 
Post-order traversal of the tree formed by the given preorder and inorder D E B F G H C A

복잡성 분석

시간 복잡성

주어진 선주문 배열을 한 번만 순회하므로 시간이 복잡해집니다. O (N).

inorder 배열에서 노드의 인덱스를 검색하는 것은 해싱으로 인해 O (1) 시간이 걸립니다.

공간 복잡성

해시 맵 (크기 n)의 추가 공간을 사용하므로 공간 복잡성도 O (N).

참조