티스토리 뷰
이진 트리는 각 노드가 최대 두 개의 자식 노드(왼쪽과 오른쪽)를 가질 수 있는 계층적 자료 구조이다.
이 구조에서 모든 노드는 데이터를 저장하며, 주로 탐색, 정렬 작업에 효율적이다. 이진 트리는 다양한 형태(예: 이진 탐색 트리, AVL 트리)로 존재한다.
우선 가장 기본적인 형태의 이진 트리로 아래와 같은 조직도를 구현하려고 한다.
코드와 함께 살펴보자.
#include <iostream>
#include <deque>
#include <queue>
using namespace std;
struct node {
string position; // 각 노드는 'position'이라는 문자열을 가지며, 직책을 나타낸다.
node* first; // 'first' 포인터는 첫 번째 자식 노드를 가리킨다.
node* second; // 'second' 포인터는 두 번째 자식 노드를 가리킨다.
};
struct org_tree {
node* root; // 'org_tree'는 'root' 노드 포인터를 가지며, 트리의 시작점을 나타낸다.
/* root node 생성 */
static org_tree create_org_structure(const string& pos) {
org_tree tree;
tree.root = new node{pos, NULL, NULL}; // 새로운 트리를 생성하고, 루트 노드를 초기화한다.
return tree;
}
/* root, first, second 순으로 검색 */
static node* find(node* root, const string& value) {
// 주어진 직책의 이름을 가진 노드를 찾는 함수이다.
if(root == nullptr) return nullptr;
if(root -> position == value) return root;
auto firstFound = org_tree::find(root -> first, value);
if(firstFound != nullptr) return firstFound;
return org_tree::find(root -> second, value);
}
bool addSubordinate(const string& manager, const string& subordinate) {
// 특정 직책 아래에 새로운 하위 직책을 추가하는 함수이다.
auto managerNode = org_tree::find(root, manager);
// 관리자 노드가 존재하지 않을 경우 false를 반환한다.
if(!managerNode) {
cout << manager << "을 찾을 수 없습니다: " << endl;
return false;
}
// 두 자식 노드가 이미 존재하는 경우, 추가할 수 없다.
if(managerNode->first && managerNode->second) {
cout << manager << " 아래에 " << subordinate << "을 추가할 수 없습니다. " << endl;
return false;
}
// 첫 번째 또는 두 번째 자식 노드에 새로운 노드를 추가한다.
if(!managerNode->first)
managerNode->first = new node {subordinate, NULL, NULL};
else
managerNode->second = new node{subordinate, NULL, NULL};
cout << manager << " 아래에 " << subordinate << "을(를) 추가했습니다. " << endl;
return true;
}
// 각각의 순회 함수들은 트리를 다양한 방법으로 탐색하여 출력한다.
/* pre order: root -> first -> second
*
* out: CEO, 부사장, IT부장, 보안팀장, 앱개발팀장, 마케팅부장, 물류팀장, 홍보팀장
* */
static void preOrder(node* start) {
if(!start) return;
cout << start -> position << ", ";
preOrder(start->first);
preOrder(start->second);
}
/* in order: first -> root -> second
*
* out: 보안팀장, IT부장, 앱개발팀장, 부사장, 물류팀장, 마케팅부장, 홍보팀장, CEO
* */
static void inOrder(node* start) {
if(!start) return;
inOrder(start->first);
cout << start->position << ", ";
inOrder(start->second);
}
/* post order: first -> second -> root
*
* out: 보안팀장, 앱개발팀장, IT부장, 물류팀장, 홍보팀장, 마케팅부장, 부사장, CEO
* */
static void postOrder(node* start) {
if(!start) return;
postOrder(start->first);
postOrder(start->second);
cout << start -> position << ", ";
}
/* level order: from the top node to bottom. from left to right.
*
* out:
* CEO,
* 부사장,
* IT부장, 마케팅부장,
* 보안팀장, 앱개발팀장, 물류팀장, 홍보팀장
*
* */
static void levelOrder(node* start) {
if(!start) return;
queue<node*> q;
q.push(start);
while(!q.empty()) {
int size = q.size();
for(int i = 0; i < size; i++) {
auto current = q.front();
q.pop();
cout << current->position << ", ";
if(current->first) q.push(current->first);
if(current->second) q.push(current->second);
}
cout << endl;
}
}
};
int main() {
auto tree = org_tree::create_org_structure("CEO");
tree.addSubordinate("CEO", "부사장");
tree.addSubordinate("부사장", "IT부장");
tree.addSubordinate("부사장", "마케팅부장");
tree.addSubordinate("IT부장", "보안팀장");
tree.addSubordinate("IT부장", "앱개발팀장");
tree.addSubordinate("마케팅부장", "물류팀장");
tree.addSubordinate("마케팅부장", "홍보팀장");
tree.addSubordinate("부사장", "재무부장");
//tree.preOrder(tree.root);
//tree.inOrder(tree.root);
//tree.postOrder(tree.root);
//tree.levelOrder(tree.root);
}
...? indent가 조금 이상하게 잡히네...?
level order만 조금 더 설명을 붙이자면, 먼저 루트 노드를 방문하고, 그 다음에 자식 노드를 방문한다. 자식 노드를 방문할 때, 해당 노드의 자식 노드를 모두 queue에 추가한다. 그리고 나서 현재 레벨의 모든 노드 방문이 끝나면 큐에 저장된 꺼내어 방문한다.
이 작업을 큐가 완전히 빌 때까지 반복하면 level 순회 작업이 완료된다.
이진 트리의 원소 순회는 워낙 간단해서... 주석으로 설명한 거 이외에 딱히 설명할 게 없는 거 같다.
끝!
반응형
'C++ > 연습 문제' 카테고리의 다른 글
[C++] Binary Search Tree (0) | 2024.01.06 |
---|---|
[C++] 연습 문제 2. 빠르고 범용적인 데이터 저장 컨테이너 구현 (0) | 2023.12.17 |
[C++] 연습 문제 1. 동적 크기 배열 구현 (0) | 2023.12.16 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- 인천 구월동 이탈리안 맛집
- 이탈리안 레스토랑
- 정보보안기사 #실기 #정리
- AsyncStorage
- 파니노구스토
- redux
- Async
- 인천 구월동 맛집
- redux-thunk
- react-native
- Promise
- await
- 맛집
- react
- javascript
- Total
- Today
- Yesterday