[트리]
1. 트리 란?
트리(Tree)는 계층적인 구조를 나타내는 자료구조로, 노드(node)들이 간선(edge)으로 연결되어 있는 구조를 갖는다. 각 노드는 하나의 부모(parent) 노드와 여러 개의 자식(child) 노드를 가질 수 있다. 트리는 데이터를 효율적으로 조직화하고 검색하는 데 사용된다.
배열, 연결리스트, 스택, 큐 등은 모두 1차원 선형적인 구조를 가지는데 비해 트리는 2차원적인 구조를 가진다.
트리 용어
노드(Node): 트리의 기본 구성 요소로, 데이터를 저장하는 요소입니다. 각 노드는 부모와 자식 노드 간의 연결을 갖습니다.
루트 노드(Root Node): 트리의 시작점에 위치한 최상위 노드를 가리킵니다. 트리는 하나의 루트 노드만을 가집니다.
부모 노드(Parent Node): 어떤 노드의 바로 위에 위치한 노드를 가리킵니다. 부모 노드는 해당 노드에 대한 직접적인 상위 계층을 형성합니다.
자식 노드(Child Node): 어떤 노드의 바로 아래에 위치한 노드를 가리킵니다. 자식 노드는 해당 노드에 대한 하위 계층을 형성합니다.
리프 노드(Leaf Node): 자식이 없는 노드로, 트리의 가장 끝단에 위치한 노드를 가리킵니다.
서브트리(Subtree): 트리 내의 어떤 노드와 그 자손 노드들로 이루어진 부분 트리를 가리킵니다.
차수(Degree): 어떤 노드가 가지고 있는 자식의 개수를 가리킵니다. 노드의 차수는 해당 노드의 서브트리 개수와도 관련이 있습니다.
높이(Height): 트리의 루트 노드에서 가장 깊숙한 리프 노드까지의 거리를 가리킵니다. 높이는 가장 긴 경로에 있는 에지의 개수와 동일합니다.
깊이(Depth): 어떤 노드가 루트 노드에서부터 얼마나 깊이 위치해 있는지를 가리킵니다.
부모-자식 관계(Parent-Child Relationship): 트리에서 각 노드는 부모와 하나 이상의 자식을 가질 수 있는데, 이것이 트리의 계층적인 구조를 형성합니다.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | #include <stdio.h> #include <stdlib.h> //& 트리 노드 구조체 정의 typedef struct TreeNode { int data; struct TreeNode* left; struct TreeNode* right; } TreeNode; //& 새로운 노드 생성 함수 TreeNode* createNode(int data) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); if (newNode != NULL) { newNode->data = data; newNode->left = NULL; newNode->right = NULL; } return newNode; } //& 이진 트리에 노드 추가 함수 TreeNode* insertNode(TreeNode* root, int data) { if (root == NULL) { return createNode(data); } if (data < root->data) { //& 왼쪽 서브트리에 노드 추가 root->left = insertNode(root->left, data); } else if (data > root->data) { //& 오른쪽 서브트리에 노드 추가 root->right = insertNode(root->right, data); } return root; } //& 이진 트리 전위 순회 함수 void preorderTraversal(TreeNode* root) { if (root != NULL) { //& 현재 노드 데이터 출력 printf("%d ", root->data); //& 왼쪽 서브트리 전위 순회 preorderTraversal(root->left); //& 오른쪽 서브트리 전위 순회 preorderTraversal(root->right); } } //& 이진 트리 중위 순회 함수 void inorderTraversal(TreeNode* root) { if (root != NULL) { //& 왼쪽 서브트리 중위 순회 inorderTraversal(root->left); //& 현재 노드 데이터 출력 printf("%d ", root->data); //& 오른쪽 서브트리 중위 순회 inorderTraversal(root->right); } } //& 이진 트리 후위 순회 함수 void postorderTraversal(TreeNode* root) { if (root != NULL) { //& 왼쪽 서브트리 후위 순회 postorderTraversal(root->left); //& 오른쪽 서브트리 후위 순회 postorderTraversal(root->right); //& 현재 노드 데이터 출력 printf("%d ", root->data); } } //& 이진 트리에서 노드 검색 함수 TreeNode* searchNode(TreeNode* root, int key) { if (root == NULL || root->data == key) { //& 노드를 찾거나 노드가 NULL인 경우 반환 return root; } if (key < root->data) { //& 왼쪽 서브트리에서 검색 return searchNode(root->left, key); } else { //& 오른쪽 서브트리에서 검색 return searchNode(root->right, key); } } int main() { TreeNode* root = NULL; //& 노드 추가 root = insertNode(root, 50); insertNode(root, 30); insertNode(root, 20); insertNode(root, 40); insertNode(root, 70); insertNode(root, 60); insertNode(root, 80); //& 순회 출력 printf("전위 순회: "); preorderTraversal(root); printf("\n"); printf("중위 순회: "); inorderTraversal(root); printf("\n"); printf("후위 순회: "); postorderTraversal(root); printf("\n"); //& 노드 검색 int key = 40; TreeNode* searchedNode = searchNode(root, key); if (searchedNode != NULL) { printf("노드 %d를 찾았습니다.\n", key); } else { printf("노드 %d를 찾을 수 없습니다.\n", key); } return 0; }// main | cs |
위 코드예제는 이진 트리를 구현하고, 전위 순회, 중위 순회, 후위 순회를 수행하는 함수들을 만들었다. 또한, 이진 트리에서 특정 노드를 검색하는 함수도 구현 했다.
'프로그래밍 > C 언어(정리)' 카테고리의 다른 글
C언어] 검색-이진검색 (0) | 2024.01.02 |
---|---|
C언어] 검색-선형검색 (0) | 2024.01.02 |
C언어] 큐 (0) | 2024.01.02 |
C언어] 스택 (0) | 2024.01.01 |
C언어] 이중 연결 리스트 (1) | 2024.01.01 |