일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 삼성 기출
- DP
- 에라토스테네스의 체
- 맛집
- 삼성 SDS 대학생 알고리즘 특강
- BFS
- 해커랭크
- 다이나믹 프로그래밍
- dynamic programming
- BOJ
- 소수
- dfs
- 브루트포스
- 시뮬레이션
- 완전탐색
- sw expert academy
- 잠실
- SWEA
- koitp
- hackerrank
- 알고리즘
- Algorithm
- PS
- 그리디
- 구현
- C++
- 백준
- 백트래킹
- 동적 계획법
- 스택
- Today
- Total
펭로그
[C++] 백준 BOJ 5639 이진 검색 트리 본문
문제링크 : https://noj.am/5639
이진 트리를 구성하고 있는 각 노드는 다음과 같이 표현한다.
V - 부모 노드
L - 왼쪽 자식 노드
R - 오른쪽 자식 노드
이진 트리의 순회 방식은 다음과 같다.
전위 순회 : V-L-R
중위 순회 : L-V-R
후위 순회 : L-R-V
문제에서 주어진 다음 조건을 보면 힌트를 유추할 수 있다.
이진 검색 트리는 다음과 같은 세 가지 조건을 만족하는 이진 트리이다.
- 노드의 왼쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 작다.
- 노드의 오른쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 크다.
- 왼쪽, 오른쪽 서브트리도 이진 검색 트리이다.
입력으로 전위순회를 시행했을 때의 결과가 주어진다고 했기 때문에 위의 원리를 그대로 적용해보면 각 노드별 서브트리를 구할 수 있다.
50 30 24 5 28 45 98 52 60
V-L-R의 순서로 순회할 때 가장 먼저 방문하는 노드(빨간색)는 루트 노드(V)이고,
조건1에 따라 50보다 작은 모든 노드(파란색)는 왼쪽 서브트리이고,
조건2에 따라 50보다 큰 모든 노드(초록색)는 오른쪽 서브트리이다.
우리는 이 V-L-R의 순서를 L-R-V로 바꿔야한다.
따라서, L sub와 R sub를 재귀적인 방법으로 다시 탐색하고 모든 탐색이 끝난 후 V를 출력해주면 될 것이다.
재귀적인 방법을 쭉 나열해보면 아래와 같이 시행된다.
* 각 시행마다 진하게 표시된 글자는 다음 시행에서 실행될 프로시저를 의미
* 컬러로 표시된 글자는 이전 시행에서의 결과를 의미
위 이미지가 너무 빠르다면 클릭
↓↓↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // BOJ 5639 이진 검색 트리 #include <iostream> #include <vector> using namespace std; vector<int> arr; void preToPost(int l, int r) { int ans = l; // 현재 노드(부모노드) int sub = l++; // 좌,우 서브트리를 나누는 인덱스 while (arr[++sub] < arr[ans]); // 인덱스 계산 // 좌측 서브트리 if (l <= sub - 1) preToPost(l, sub - 1); // 우측 서브트리 if (sub <= r) preToPost(sub, r); cout << arr[ans] << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); freopen("../input.txt", "r", stdin); int input; while (cin >> input) arr.push_back(input); arr.push_back(INT32_MAX); // segment fault 방지 preToPost(0, arr.size() - 2); return 0; } | cs |
참고로 다음 코드는
29 | arr.push_back(INT32_MAX); // segment fault 방지 | cs |
이 부분에서 arr.size()를 초과하는 범위를 탐색했을 경우 컴파일 에러가 나기 때문에 아무 의미 없는 int의 MAX 값을 넣은 것이다.
12 | while (arr[++sub] < arr[ans]); // 인덱스 계산 | cs |
아니면 다음과 같이 표현해도 된다.
12 | while (++sub < arr.size() && arr[sub] < arr[ans]); // 인덱스 계산 | cs |
'Study > PS(Algorithm)' 카테고리의 다른 글
[C++] 문자열 계산기 (6) | 2018.10.18 |
---|---|
[C++] 백준 BOJ 14890 경사로 (SWEA 4014 활주로 건설) (0) | 2018.10.13 |
[C++] 백준 BOJ 6603 로또 (0) | 2018.10.08 |
[C++] 백준 BOJ 9935 문자열 폭발 (0) | 2018.10.08 |
[C++] 백준 BOJ 9095 1,2,3 더하기 (0) | 2018.10.06 |