목차
- 이진 트리 란?
- 이진 트리의 특징
- 이진 트리 예시
- 이진 트리 구현
- 이진 트리 응용(트리 복원)
- 트리 문제(BOJ)
이진 트리(Binary Tree) 란?
- 이진 트리는 가장 많이 사용되는 비선형 자료구조 이다.
- 이진 트리는 데이터의 탐색 속도 증진 을 위해 사용하는 구조이다.
이진 트리(Binary Tree)의 특징
- 힙 정렬(Heap Sort)을 구현할 때 이진 트리를 이용하여 구현할 수 있다.
- 이진 트리에서 데이터를 탐색 하는 방법은 크게 세 가지 방법이 있다.
- 전위 순회 (Preorder Traversal)
- 자기 자신을 먼저 처리한다.
- 왼쪽 자식을 방문.
- 오른쪽 자식을 방문
- 중위 순회 (Inorder Traversal)
- 왼쪽 자식을 방문.
- 자기 자신을 먼저 처리한다.
- 오른쪽 자식을 방문
- 후위 순회 (Postorder Traversal)
- 왼쪽 자식을 방문
- 오른쪽 자식을 방문.
- 자기 자신을 먼저 처리한다.
- 이진트리(Binary Tree) 형태
- 전위 순회 (Preorder Traversal)
- 자기 자신을 먼저 처리한다.
- 왼쪽 자식을 방문.
- 오른쪽 자식을 방문
- 중위 순회 (Inorder Traversal)
- 왼쪽 자식을 방문.
- 자기 자신을 먼저 처리한다.
- 오른쪽 자식을 방문
- 후위 순회 (Postorder Traversal)
- 왼쪽 자식을 방문
- 오른쪽 자식을 방문.
- 자기 자신을 먼저 처리한다.
이진 트리(Binary Tree)의 알고리즘 예시
- 전위 순회 (Preorder Traversal) 1 - 2 - 4 - 5 - 3 - 6 - 7
- 중위 순회 (Inorder Traversal) 4 - 2 - 5 - 1 - 6 - 3 - 7
- 후위 순회 (Postorder Traversal) 4 - 5 - 2 - 6 - 7 - 3 - 1
이진 트리(Binary Tree) C++ 구현
트리 응용
- 전위 순회(pre order) 결과가 주어졌을때 트리 복원하기
- -1은 노드 끝을 의미합니다.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
typedef pair<int,int> pi;
vector<pi> tree[10000];
vector<int> restore;
int visit[10000];
stack<int> s;
void makeTree(int idx, int node, vector<int> &v) {
visit[idx] = 1;
//end node
if(v[idx] == -1) {
//left
if(tree[node][0].first == -2) {
tree[node][0].first = -1;
}
else { // right
tree[node][0].second = -1;
}
return;
}
//not to exist node
if(tree[v[idx]].empty()) {
s.push(v[idx]);
tree[v[idx]].push_back({-2,-2});
}
//exist node
if(tree[node][0].first == -2) {
tree[node][0].first = v[idx];
} else if(tree[node][0].second == -2) {
tree[node][0].second = v[idx];
}
makeTree(idx+1,v[idx],v);
}
void traversal(int node) {
if(node == -1) {
restore.push_back(-1);
return;
}
else if(node > 0) {
restore.push_back(node);
traversal(tree[node][0].first);
traversal(tree[node][0].second);
}
}
bool solve(vector<int> &v) {
int root = v[0];
if(root == -1) {
return true;
}
visit[0] = 1;
tree[root].push_back({-2,-2});
s.push(root);
int cur = root;
for (int i = 1; i < v.size(); i++) {
if(!visit[i]) {
makeTree(i, cur, v);
if(!s.empty()) {
cur = s.top(); s.pop();
}
}
}
traversal(root);
for (int i = 1; i < v.size(); i++) {
if(restore.size()!=v.size()) return false;
if(restore[i]!=v[i]) {
return false;
}
}
return true;
}
int main(void) {
vector<int> test1 = {-1};
vector<int> test2 = {3,5,6,8,-1,-1,-1,1,7,-1,-1,-1,4,-1,2,-1,-1};
vector<int> test3 = {1,-1,2,-1,-1,3,-1,-1};
cout << solve(test1) << "\n";
cout << solve(test2) << "\n";
cout << solve(test3) << "\n";
return 0;
}