반응형
트리의 순회(https://www.acmicpc.net/problem/2263)
1. 이해하기
- 인오더와 포스트오더로 나타내어진 트리를 프리오더로 나타내는 것이다.
- 인오더는 left root right, 포스트오더는 left right root 형태로 나타내어진다.
- 포스트오더에서 가장 오른쪽이 root이므로 이것을 이용해 인오더에서 left의 길이를 구한다. 구한 길이를 바탕으로 왼쪽과 오른쪽을 분할하여 다시 구한다.
2. 구현하기
-
solve(is,ie,ps,pe): 인오더의 시작,끝점과 포스트오더의 시작,끝점을 받는다.
- 포스트오더에서 구한 root를 가지고 인오더에서 root의 위치(ir)를 찾는다. 그 이후에 루트의 왼쪽에 해당하는 길이(l)를 구하고 그 길이를 바탕으로 트리의 왼쪽과 오른쪽을 분할한다.
- solve(is,ir-1,ps,ps+l-1) - 왼쪽
- solve(ir+1,ie,ps+l,pe-1) - 오른쪽
void solve(int is, int ie, int ps, int pe) { if(is > ie or ps > pe) return; int root = postorder[pe]; cout << root << ' '; int ir = position[root]; int left = ir-is; solve(is,ir-1,ps,ps+left-1); solve(ir+1,ie,ps+left,pe-1); }
-
position은 inorder에서 숫자의 위치를 담고 있는 배열이다. root를 inorder에서 찾기위해 반복문을 이용해도 되지만 한번에 찾아내기 위하여 position배열을 이용한다.
3. 전체코드
#include <iostream>
using namespace std;
int inorder[100000], postorder[100000];
int position[100001];
void solve(int is, int ie, int ps, int pe) {
if(is > ie or ps > pe) return;
int root = postorder[pe];
cout << root << ' ';
int ir = position[root];
int left = ir-is;
solve(is,ir-1,ps,ps+left-1);
solve(ir+1,ie,ps+left,pe-1);
}
int main() {
int n;
cin >> n;
for(int i = 0; i < n; i++) cin >> inorder[i];
for(int i = 0; i < n; i++) cin >> postorder[i];
for(int i = 0; i < n; i++) {
position[inorder[i]] = i;
}
solve(0,n-1,0,n-1);
cout << '\n';
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 9466번 텀프로젝트 (0) | 2020.02.03 |
---|---|
[백준] 1074번 Z (0) | 2019.12.17 |
[백준] 10815번 숫자 카드 (0) | 2019.12.11 |
[백준] 2873번 롤러코스터 (0) | 2019.12.11 |
[백준] 2098번 외판원 순회 (0) | 2019.11.13 |