https://www.acmicpc.net/problem/5639
5639번: 이진 검색 트리
트리를 전위 순회한 결과가 주어진다. 노드에 들어있는 키의 값은 106보다 작은 양의 정수이다. 모든 값은 한 줄에 하나씩 주어지며, 노드의 수는 10,000개 이하이다. 같은 키를 가지는 노드는 없다
www.acmicpc.net
이진 검색 트리는 다음과 같은 세 가지 조건을 만족하는 이진 트리이다.
- 노드의 왼쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 작다.
- 노드의 오른쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 크다.
- 왼쪽, 오른쪽 서브트리도 이진 검색 트리이다.
전위 순회 (루트-왼쪽-오른쪽)은 루트를 방문하고, 왼쪽 서브트리, 오른쪽 서브 트리를 순서대로 방문하면서 노드의 키를 출력한다. 후위 순회 (왼쪽-오른쪽-루트)는 왼쪽 서브트리, 오른쪽 서브트리, 루트 노드 순서대로 키를 출력한다. 예를 들어, 위의 이진 검색 트리의 전위 순회 결과는 50 30 24 5 28 45 98 52 60 이고, 후위 순회 결과는 5 28 24 45 30 60 52 98 50 이다.
이진 검색 트리를 전위 순회한 결과가 주어졌을 때, 이 트리를 후위 순회한 결과를 구하는 프로그램을 작성하시오.
키의 중복이 없고, 이진검색트리이다. 전위 순회 결과가 주어졌을떄, 트리를 만드는 과정이 필요했다.
어떻게 이진 검색 트리를 만들어야하는가?
사실 이부분이 제일 중요한 것 같다.
입력을 받을 떄마다, 트리를 새로 만들어주고, 이 트리와 루트를 비교하는 과정이 있다.
1)루트가 아직 NULL인 경우
이 경우 그냥 루트를 새로 만든 트리로 설정하면 끝이다.
만약 50을 넣는다고 하자. 이 경우 그냥 루트를 50으로 설정하면 끝난다.
2)루트보다 트리의 키 값이 작은 경우
만약 루트의 키 값이 50이고 새로 만든 트리의 키 값이 30이라고 가정해보자.
이 경우에서 나는 한 가지 경우만 생각했지만, 2의 경우에도 크게 2가지로 나뉘게 된다.
2-1) 루트의 왼쪽 노드가 존재하지 않는 경우
만약 50을 넣고, 키 값 30인 새로운 노드를 트리에 삽입해야 한다.
아까 50을 넣어두었을 떄, 50의 왼쪽은 NULL이기 떄문에, 루트의 왼쪽 자식으로 새로 만든 노드를 넣어준다.
2-2) 루트의 왼쪽 노드가 존재 하는 경우
이제 위 그림 30까지 넣은 상태에서 새로운 키 값인 25인 노드를 삽입해야 한다고 해보자.
먼저 루트를 가리키는 노드 temp를 새로 만들고, temp의 왼쪽 자식이 없을 떄까지 temp를 왼쪽으로 쭉 이동시킨다.
그 후 temp의 왼쪽 자식이 없다면 temp의 왼쪽 자식에 새로운 노드를 추가한다.
3)루트보다 트리의 키값이 큰 경우
문제에서 키 값의 중복이 없다고 했으므로, 루트보다 트리의 키 값이 큰 경우를 생각해보자.
이 경우도 마찬가지로 2가지로 나뉘게 된다.
3-1) 루트의 오른쪽 자식이 존재하지 않는 경우
이제 50-30-25를 순서대로 넣어서, 이진검색 트리가 존재한다고 생각해보자.
키 값이 100인 노드를 이진 검색 트리에 삽입해야 한다고 해보자.
루트의 오른쪽에는 아직 자식이 없으므로, 이 경우 루트의 오른쪽 자식을 새 노드로 만들어 주면 끝이다.
3-2) 루트의 오른쪽 자식이 존재하는 경우
2-2)와 마찬가지로 수행하는데 오른쪽으로 이동하면 된다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n = 0;
int Data;
//구조체 생성
struct node{
int data;
node *left = NULL;
node *right = NULL;
};
//루트 노드
node *rootnode;
//노드 삽입
/*
루트가 NULL인경우,
루트보다 키 값이 작은 경우
루트보다 키 값이 큰 경우
*/
void insertNode(int data){
node *newnode = new node;
newnode->data = data;
newnode->left = NULL;
newnode->right = NULL;
if(n == 0){
rootnode = newnode;
}
else{
node *temp = rootnode;
while(1){
if(temp->data > newnode->data){
if(temp->left == NULL){
temp->left = newnode;
break;
}
else{
temp = temp->left;
}
}
else if(temp->data < newnode->data){
if(temp->right == NULL){
temp->right = newnode;
break;
}
else{
temp = temp->right;
}
}
}
}
}
void input(){
while(cin >> Data){
insertNode(Data);
n += 1;
}
}
void postorder(node *root){
if(root == NULL){
return;
}
postorder(root->left);
postorder(root->right);
cout << root->data << ' ';
}
int main(void){
input();
postorder(rootnode);
}
'자료구조' 카테고리의 다른 글
백준 15926 현욱은 괄호왕이야!! C++ (0) | 2022.08.24 |
---|---|
백준 20044 Project Teams C++ (0) | 2022.06.15 |
백준 1991 트리 순회 C++ (0) | 2022.06.03 |
백준 23056 참가자 명단 C++ (0) | 2022.06.01 |
백준 수 정렬하기 3 (0) | 2022.05.20 |