Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

중위 순회와 후위 순회로 이진 트리의 전위 순회 구하기


이 문제에서는 이진 트리의 중위 순회(inorder)후위 순회(postorder) 결과가 주어지며, 우리의 목표는 해당 트리의 전위 순회(preorder) 결과를 출력하는 것입니다.

먼저 예시를 통해 문제를 살펴보겠습니다.

Input:
inorder: 16 7 21 12 1 5 9
postorder: 16 21 7 1 9 5 12

Output:
preorder: 12 7 16 21 5 1 9

위 입력값에 대응하는 이진 트리는 다음과 같습니다.

중위 순회와 후위 순회로 이진 트리의 전위 순회 구하기

문제 해결 접근 방법

가장 단순한 방법은 주어진 두 순회 결과로 트리를 직접 생성한 뒤, 완성된 트리를 다시 전위 순회하는 것입니다. 하지만 이 방식은 트리를 실제로 구성해야 하므로 구현이 복잡하고 시스템에도 큰 부담을 줍니다.

보다 효율적인 해결책은 스택(stack) 자료구조를 활용하는 것입니다. 핵심 아이디어는 다음과 같습니다.

  • 후위 순회의 마지막 원소가 곧 트리의 루트(root)입니다.
  • 중위 순회에서 루트를 기준으로, 루트보다 앞에 있는 원소들은 모두 왼쪽 서브트리에, 뒤에 있는 원소들은 오른쪽 서브트리에 속합니다.
  • 루트를 찾으면 오른쪽 서브트리 → 왼쪽 서브트리 순서로 재귀적으로 탐색하면서 각 노드의 값을 스택에 저장(push)합니다.
  • 모든 탐색이 끝난 뒤 스택에서 원소를 하나씩 꺼내면(pop), 루트 → 왼쪽 서브트리 → 오른쪽 서브트리 순서인 전위 순회 결과를 얻을 수 있습니다.

이렇게 하면 트리를 실제로 만들지 않고도 주어진 순회 정보만으로 전위 순회를 빠르게 계산할 수 있습니다.

자바(Java) 구현 예제

import java.util.Stack;
public class Main {
    static int postIndex;
    void preOrder(int[] in, int[] post, int inStrt, int inEnd, Stack<Integer> preorder) {
        if (inStrt > inEnd)
            return;
        int val = post[postIndex];
        int inIndex = searchValue(in, val);
        postIndex--;
        preOrder(in, post, inIndex + 1, inEnd, preorder);
        preOrder(in, post, inStrt, inIndex - 1, preorder);
        preorder.push(val);
    }
    void printPreOrderTraversal(int[] in, int[] post) {
        int len = in.length;
        postIndex = len - 1;
        Stack<Integer> preorder = new Stack<Integer>();
        preOrder(in, post, 0, len - 1, preorder);
        while (preorder.empty() == false)
            System.out.print(preorder.pop() + " ");
    }
    int searchValue(int[] in, int data) {
        int i = 0;
        for (i = 0; i < in.length; i++)
            if (in[i] == data)
                return i;
        return i;
    }
    public static void main(String args[]) {
        int in[] = { 4, 10, 12, 15, 18, 22, 24, 25, 31, 35, 44, 50, 66, 70, 90 };
        int post[] = { 4, 12, 10, 18, 24, 22, 15, 31, 44, 35, 66, 90, 70, 50, 25 };
        Main tree = new Main();
        System.out.println("Preorder Traversal of the tree is: ");
        tree.printPreOrderTraversal(in, post);
    }
}

실행 결과

Preorder Traversal of the tree is:
25 15 10 4 12 22 18 24 50 35 31 44 70 66 90