백준 트리 순회 문제 풀이
이진트리
이진 트리는 각 노드가 최대 두 개의 자식 노드를 갖는 트리 구조를 말한다. 이진 트리는 컴퓨터 과학에서 가장 기본적인 자료 구조 중 하나로, 다양한 문제에 활용된다.
이진 트리의 순회
이진 트리의 모든 노드를 방문하는 방법을 순회(traversal)라고 한다. 이진 트리의 순회에는 크게 세 가지 방법이 있다.
- 전위 순회 (Preorder Traversal) : 루트 노드 -> 왼쪽 서브 트리 -> 오른쪽 서브 트리 순으로 방문
- 중위 순회 (Inorder Traversal) : 왼쪽 서브 트리 -> 루트 노드 -> 오른쪽 서브 트리 순으로 방문
- 후위 순회 (Postorder Traversal) : 왼쪽 서브 트리 -> 오른쪽 서브 트리 -> 루트 노드 순으로 방문
이진 트리의 순회는 대부분 재귀로 구현된다.
// 전위 순회
void static preorder(Tree* root) {
if(root){
cout << root -> data << "\n";
preorder(root -> left);
preorder(root -> right);
}
// 중위 순회
void inorder(Tree* root) {
if(root){
inorder(root -> left);
cout << root -> data << "\n";
inorder(root -> right);
}
// 후위 순회
void postorder(Tree* root) {
if(root){
inorder(root -> left);
inorder(root -> right);
cout << root -> data << "\n";
}
이진 트리의 구현
이진 트리는 포인터를 이용해 구현할 수 있다. 각 노드는 데이터와 왼쪽 자식 노드, 오른쪽 자식 노드를 가리키는 포인터를 갖는다.
class Tree{
int data;
Tree *left;
Tree *right;
};
PS코드
이진트리의 순회를 구현하는 가장 기본적인 백준문제를 풀면서 실제로 구현을 연습해볼 수 있다.
#include <bits/stdc++.h>
using namespace std;
class Tree{
char root;
Tree* left;
Tree* right;
public:
//노드 생성자
Tree(){
root = ' ';
left = NULL;
right = NULL;
}
//루트노드 설정
void setRoot(char root){
this -> root = root;
}
//왼쪽 서브 트리 설정
void setLeft(Tree* left){
this -> left = left;
}
//오른쪽 서브 트리 설정
void setRight(Tree* right){
this -> right = right;
}
//전위 순회
void static preorder(Tree* r) {
if (r) {
cout << r->root;
preorder(r->left);
preorder(r->right);
}
}
//중위 순회
void static inorder(Tree* r) {
if (r) {
inorder(r->left);
cout << r->root;
inorder(r->right);
}
}
//후위 순회
void static postorder(Tree* r) {
if (r) {
postorder(r->left);
postorder(r->right);
cout << r->root;
}
}
};
int main(void){
cin.tie(NULL);
cout.tie(NULL);
ios::sync_with_stdio(false);
int n;
cin >> n;
Tree *tree = new Tree[n];
for (int i = 0; i < n; ++i) {
char root,left,right;
cin >> root >> left >> right;
if(root!='.')
tree[(int)(root-'A')].setRoot(root);
if (left != '.')
tree[(int)(root - 'A')].setLeft(&tree[(int)(left - 'A')]); // 왼쪽서브트리 형성을 위한 입력
else
tree[(int)(root - 'A')].setLeft(NULL);
if (right != '.')
tree[(int)(root - 'A')].setRight(&tree[(int)(right - 'A')]); // 오른쪽서브트리 형성을 위한 입력
else
tree[(int)(root - 'A')].setRight(NULL);
}
Tree *root = &tree[0]; // 항상 A노드가 루트노드이므로
Tree::preorder(root);
cout << "\n";
Tree::inorder(root);
cout << "\n";
Tree::postorder(root);
cout << "\n";
}
참고자료
https://hongku.tistory.com/160 https://www.acmicpc.net/problem/1991
댓글남기기