[BOJ알고리즘, C++]#4256_트리, 트리의 순회, 두 가지 순회를 통해 다른 하나의 순회 찾기 유형

2024. 5. 21. 21:05· 문제 풀이/BOJ 문제 풀이
목차
  1. #1. 문제
  2. #2. 풀이
  3. 1. 트리의 순회
  4. 2. 전위 순회에서 루트 노드 찾고, 중위 순회에서 왼쪽과 오른쪽 서브트리 분할!
  5. #3. 코드

 

#1. 문제

https://www.acmicpc.net/problem/4256

 


 

#2. 풀이

 

1. 트리의 순회

 

[자료구조]#5_트리

[자료구조]#5_트리 트리 자료구조에 대해 알아보겠습니다.  Overview 개념이진트리순회이진 탐색 트리균형 이진트리AVL 트리레드-블랙 트리Map, Set힙 #0. 개념1. 트리? [정의] : 트리는 1:n 관계의

webddevys.tistory.com

트리 자료구조는 세 가지 순회 방법을 갖습니다. 모두 현재 노드를 기준으로 (1) 전위 순회(루트->왼쪽->오른쪽), (2) 중위 순회(왼쪽->루트->오른쪽), 그리고 (3) 후위 순회(왼쪽->오른쪽->루트)가 있습니다. 대부분의 경우, 주어진 트리 자료구조의 두 가지 순회 내용을 알려주고, 다른 하나의 순회 내용을 구하는 문제가 나옵니다.

 

2. 전위 순회에서 루트 노드 찾고, 중위 순회에서 왼쪽과 오른쪽 서브트리 분할!

전위 순회: [ 루트 노드 | 왼쪽 서브트리 | 오른쪽 서브트리 ]
중위 순회: [ 왼쪽 서브트리 | 루트 노드 | 오른쪽 서브트리 ]
  1. 현재 전위 순회 목록의 첫 번째 노드는 루트 노드입니다. 이어서, 두 번째 노드는 왼쪽 서브트리의 루트 노드가 됩니다. 이를 활용해, 전위 순회 목록을 차례대로 순회하며 중위 순회 목록에서 해당 노드를 찾아 왼쪽 서브트리와 오른쪽 서브트리로 분할합니다. 이어서, 현재 전위 순회 목록의 두 번째 노드는 왼쪽 서브트리의 루트 노드가 되며, 이전 중위 순회 목록에서 분할되어 나온 '왼쪽 서브트리'의 루트 노드가 됩니다.
  2. 전위 순회를 차례대로 순회 -> 현재 위치의 노드가 루트 노드가 되어 중위 순회 목록을 분할 -> 어차피 다음 위치의 노드는 왼쪽 서브트리의 루트 노드가 되어 중위 순회 목록에서 분할되어 나온 왼쪽 서브트리에서 해당 노드를 찾아서 다시 분할....-> 왼쪽 서브트리가 끝나고 전위 순회 목록에서 그다음 위치의 노드는 또 오른쪽 서브트리의 루트 노드가 된다. 이 과정을 반복하면 자연스럽게 '왼쪽 서브트리' -> '오른쪽 서브트리' -> 루트 노드 순서가 되어 '후위 순회' 목록을 만들 수 있게 됩니다.

 


 

#3. 코드

/*
    @문제 : 이진트리(각 노드의 차수가 최대 2이하로 유지)의 전위 순회와 중위 순회를 통해 후위 순회를 구해라
    @설명
            1. 전위 순회 : [ 루트 노드 | 왼쪽 서브트리 루트 노드 | 오른쪽 서브트리 루트 노드 ]
               중위 순회 : [ 왼쪽 서브트리 | 루트 노드 | 오른쪽 서버트리 ]
               후위 순회 : [ 왼쪽 서브트리 | 오른쪽 서브트리 | 루트 노드 ]
            2. 전위 순회를 차례대로 순회하며, 현재 루트 노드, 왼쪽 서브트리 루트 노드, 오른쪽 서브트리 루트 노드를 찾는다.
            3. 중위 순회에서 '전위 순회의 현재 루트 노드'를 찾아서, 왼쪽 서브트리 오른쪽 서브 트리 분할
            4. 그러면 자연스레, 전위 순회의 다음 인덱스 위치에 있는 노드는 왼쪽 서브트리의 루트 노드가 된다.
               따라서, 왼쪽 서브 트리에 대한 재귀 호출을 진행하면, 이 루트 노드를 활용해 다시 중위 순회 목록에서 왼쪽 서브트리 오른쪽 서브트리 분할
               위 과정을 반복
*/

#include <iostream>
#include <vector>
using namespace std;

int T, n;
vector<int> pre;
vector<int> in;

int FindRootNodeInInOrder(vector<int>& in, int start, int end, int root)
{
    for(int i=start; i<=end; ++i)
    {
        if(in[i] == root)
            return i;
    }
    return -1;
}

void FindPost(vector<int>& pre, vector<int>& in, int start, int end, int& idx)
{
    if(start > end) return;

    // #1. 전위 순회 현재 루트 노드 -> 중위 순회에서 찾기
    int root = FindRootNodeInInOrder(in, start, end, pre[idx++]);

    // #2. 분할 후 왼쪽 서브트리
    FindPost(pre, in, start, root-1, idx);

    // #3. 분할 후 오른쪽 서브트리
    FindPost(pre, in, root+1, end, idx);

    // #4. 루트 노드 출력
    if(root != -1) cout << in[root] << ' ';
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> T;

    while(T--)
    {
        cin >> n;
        pre.clear();
        in.clear();
        for(int i=0; i<n; ++i)
        {
            int num;
            cin >> num;

            pre.push_back(num);
        }
        for(int i=0; i<n; ++i)
        {
            int num;
            cin >> num;

            in.push_back(num);
        }
        int idx =0;
        FindPost(pre, in, 0, n-1, idx);
        cout << '\n';
    }

    return 0;
}

 


 

 

 

 

저작자표시 (새창열림)

'문제 풀이 > BOJ 문제 풀이' 카테고리의 다른 글

[BOJ알고리즘, C++]#1135_뉴스 전하기, DFS  (0) 2024.06.19
[BOJ알고리즘, C++]#14502_연구소, 백트래킹, DFS, BFS  (1) 2024.06.19
[BOJ알고리즘, C++]#2579_계단 오르기, DP  (0) 2024.05.21
[BOJ알고리즘, C++]#15900_나무 탈출, DFS, 깊이 우선 탐색  (0) 2024.05.21
[BOJ알고리즘, C++]#13511_트리와 쿼리2, 트리, LCA, 노드 사이 거리  (0) 2024.05.21
  1. #1. 문제
  2. #2. 풀이
  3. 1. 트리의 순회
  4. 2. 전위 순회에서 루트 노드 찾고, 중위 순회에서 왼쪽과 오른쪽 서브트리 분할!
  5. #3. 코드
'문제 풀이/BOJ 문제 풀이' 카테고리의 다른 글
  • [BOJ알고리즘, C++]#1135_뉴스 전하기, DFS
  • [BOJ알고리즘, C++]#14502_연구소, 백트래킹, DFS, BFS
  • [BOJ알고리즘, C++]#2579_계단 오르기, DP
  • [BOJ알고리즘, C++]#15900_나무 탈출, DFS, 깊이 우선 탐색
Hardii2
Hardii2
Hardii2
개발 블로그
Hardii2
전체
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 웹 개발
      • Node.js
      • React
    • 게임개발
      • DirectX12
      • 관련 지식
      • Unreal C++
      • Unreal 블루프린트
    • 언어
      • Effective C++
      • Basic C++
      • 디자인 패턴
      • 자료구조
      • 기술 질문
    • 문제 풀이
      • BOJ 문제 풀이
      • Programmers 문제 풀이
      • geeksForgeeks 문제 풀이
    • 수학
      • 확률과 통계
      • 게임수학
    • 개인프로젝트
    • 그룹프로젝트
      • PM
      • Dev
    • Github

블로그 메뉴

  • 홈
  • 글쓰기

공지사항

인기 글

태그

  • unreal
  • dfs
  • 알고리즘
  • 우선순위 큐
  • DP
  • 기술 질문
  • 디자인 패턴
  • programmers
  • 정렬
  • set
  • Effective C++
  • BFS
  • 개발
  • stl
  • 그래프
  • 최단 경로
  • BOJ
  • Unreal Blueprint
  • 트리
  • C++

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Hardii2
[BOJ알고리즘, C++]#4256_트리, 트리의 순회, 두 가지 순회를 통해 다른 하나의 순회 찾기 유형
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.