2024. 11. 14. 00:08ㆍData Structure
트리(Tree) 자료구조는 계층적이고 비선형적인 구조로 데이터를 표현하는데 유용한 자료구조입니다.
그래프의 한 형태로, 서로 연결된 노드들로 구성된 트리는 많은 응용 분야에서 사용되며, 대표적인 예로 파일 시스템, 데이터베이스, 컴파일러 등이 있습니다.
이번 포스팅에서는 트리의 개념과 이를 C#으로 구현하는 방법에 대해 알아보겠습니다.
1. 트리란?
트리는 계층적 구조를 가지며 부모-자식 관계로 구성된 노드들의 집합입니다. 트리의 최상위 노드는 루트(Root)라 불리며, 루트에서 출발하여 하위 노드들(자식)로 내려갑니다. 일반적으로 트리는 여러 노드를 가질 수 있고, 노드의 개수가 많을수록 트리의 크기가 커집니다.
1.1 트리의 기본 용어
- 루트 노드 (Root Node): 트리의 최상위 노드
- 부모 노드 (Parent Node): 특정 노드와 직접 연결된 상위 노드
- 자식 노드 (Child Node): 특정 노드와 직접 연결된 하위 노드
- 잎 노드 (Leaf Node): 자식이 없는 노드
- 깊이 (Depth): 루트 노드에서 특정 노드까지의 거리
- 레벨 (Level): 트리에서 같은 깊이를 가진 노드들 집합
- 높이 (Height): 루트에서 가장 멀리 있는 잎 노드까지의 거리
1.2 트리의 특성
트리는 사이클이 없는 비순환 구조이며, 하나의 루트에서 출발하여 다른 모든 노드로 향하는 유일한 경로가 존재합니다. 각 자식 노드는 오직 하나의 부모만 가질 수 있어야 합니다.
2. 트리의 종류
트리는 여러 종류가 있으며, 각각의 트리들은 특정한 규칙에 따라 구조가 달라집니다:
- 이진 트리(Binary Tree): 각 노드는 최대 두 개의 자식을 가집니다.
- 이진 탐색 트리(Binary Search Tree, BST): 왼쪽 자식은 부모보다 작은 값을, 오른쪽 자식은 부모보다 큰 값을 가집니다.
- 균형 트리(AVL 트리, 레드-블랙 트리): 노드 삽입 및 삭제 시 균형을 유지하여 트리의 높이를 낮춥니다.
- B 트리 및 B+ 트리: 데이터베이스와 파일 시스템에서 자주 사용되는 구조입니다.
3. 트리의 구현 (C# 예제)
여기서는 가장 간단한 트리 형태를 구현하고, 기본적인 삽입과 탐색 연산을 포함한 구조를 살펴보겠습니다.
3.1 트리 노드 클래스 구현
노드는 데이터와 자식 노드를 포함하는 구조로 정의됩니다. 각 노드는 자신의 데이터와 하위 자식 노드에 대한 정보를 가지고 있습니다.
public class TreeNode
{
public int Data;
public List<TreeNode> Children;
public TreeNode(int data)
{
Data = data;
Children = new List<TreeNode>();
}
public void AddChild(TreeNode child)
{
Children.Add(child);
}
}
3.2 트리 클래스 구현
다음으로는 트리 클래스와 주요 기능을 구현해 봅시다. 트리 클래스는 루트 노드를 포함하며, 노드를 삽입하고 트리를 순회하는 기능을 가질 수 있습니다.
using System;
using System.Collections.Generic;
public class Tree
{
public TreeNode Root;
public Tree(int rootData)
{
Root = new TreeNode(rootData);
}
// DFS (Depth-First Search) 방식으로 트리 순회
public void TraverseDFS(TreeNode node)
{
if (node == null) return;
Console.WriteLine(node.Data); // 방문한 노드의 데이터 출력
foreach (var child in node.Children)
{
TraverseDFS(child); // 재귀적으로 자식 노드 탐색
}
}
// BFS (Breadth-First Search) 방식으로 트리 순회
public void TraverseBFS()
{
Queue<TreeNode> queue = new Queue<TreeNode>();
queue.Enqueue(Root);
while (queue.Count > 0)
{
var node = queue.Dequeue();
Console.WriteLine(node.Data); // 방문한 노드의 데이터 출력
foreach (var child in node.Children)
{
queue.Enqueue(child);
}
}
}
}
3.3 트리 사용 예시
public class Program
{
public static void Main()
{
// 트리 생성 및 노드 추가
Tree tree = new Tree(1); // 루트 노드 생성
tree.Root.AddChild(new TreeNode(2));
tree.Root.AddChild(new TreeNode(3));
tree.Root.Children[0].AddChild(new TreeNode(4));
tree.Root.Children[0].AddChild(new TreeNode(5));
tree.Root.Children[1].AddChild(new TreeNode(6));
Console.WriteLine("DFS Traversal:");
tree.TraverseDFS(tree.Root); // 출력: 1 2 4 5 3 6
Console.WriteLine("\nBFS Traversal:");
tree.TraverseBFS(); // 출력: 1 2 3 4 5 6
}
}
코드 설명
- TraverseDFS: 깊이 우선 탐색 방식으로 트리를 순회하며 모든 노드를 방문합니다. 루트 노드에서 시작하여 자식 노드를 재귀적으로 탐색합니다.
- TraverseBFS: 너비 우선 탐색 방식으로 트리를 순회합니다. 큐를 사용하여 같은 레벨의 모든 노드를 차례로 방문합니다.
4. 트리의 장단점
장점
- 계층적 데이터 표현: 트리는 계층적 구조로 데이터를 표현하는 데 유리합니다.
- 탐색 효율성: 특히 이진 탐색 트리, AVL 트리와 같은 트리 구조에서는 탐색, 삽입, 삭제 연산의 효율이 뛰어납니다.
단점
- 복잡한 구조: 트리의 구조가 복잡해질수록 구현 및 유지보수가 어려워질 수 있습니다.
- 불균형 가능성: 단순 이진 탐색 트리의 경우 데이터 삽입 순서에 따라 트리가 한쪽으로 치우칠 수 있습니다.
트리는 계층적 데이터 구조로서, 많은 컴퓨터 과학 및 엔지니어링 문제에 적합한 자료구조입니다.
'Data Structure' 카테고리의 다른 글
너비 우선 탐색 (BFS)의 개념 및 구현 (0) | 2024.11.18 |
---|---|
깊이 우선 탐색 (DFS)의 개념 및 구현 (0) | 2024.11.18 |
이진 탐색 트리 (Binary Search Tree)의 개념 및 구현 (0) | 2024.11.12 |
이진 트리 (Binary Tree)의 개념 및 구현 (1) | 2024.11.11 |
우선순위 큐 (Priority Queue)의 개념 및 구현 (0) | 2024.11.08 |