디스조인트 집합 (Disjoint Set)의 개념 및 구현
2024. 11. 22. 01:09ㆍData Structure
디스조인트 집합 (Disjoint Set)의 개념 및 구현
디스조인트 집합(Disjoint Set)은 겹치지 않는 여러 개의 집합을 효율적으로 관리하기 위한 자료구조입니다.
주로 집합 간의 결합(Union)과 원소의 대표 찾기(Find) 연산을 빠르게 수행하는 데 사용됩니다.
이 자료구조는 그래프의 연결성 확인과 최소 신장 트리 알고리즘(예: 크루스칼 알고리즘)에서 중요한 역할을 합니다.
1. 디스조인트 집합(Disjoint Set)이란?
디스조인트 집합은 다음과 같은 두 가지 기본 연산을 빠르게 수행하기 위한 자료구조입니다:
- Find: 특정 원소가 속한 집합의 대표 원소를 찾습니다.
- Union: 두 집합을 하나로 합칩니다.
이 자료구조는 특히 서로소 집합(겹치는 원소가 없는 집합)을 관리할 때 유용하며, 트리 기반 구조를 사용해 효율적인 구현이 가능합니다.
2. 디스조인트 집합의 주요 개념
2.1 대표 원소 (Representative Element)
각 집합에는 고유한 대표 원소가 있습니다. Find 연산을 통해 각 원소가 속한 집합의 대표 원소를 찾을 수 있습니다.
2.2 Union 연산
두 집합을 결합할 때 하나의 대표 원소를 다른 집합의 대표 원소에 연결합니다.
2.3 최적화 기법
디스조인트 집합은 다음 두 가지 기법을 활용해 성능을 극대화합니다:
- 경로 압축(Path Compression): Find 연산 중 방문한 모든 노드를 직접 대표 원소에 연결하여 트리의 높이를 줄입니다.
- 랭크 기반 합치기(Union by Rank): 두 집합을 결합할 때 트리의 높이가 낮은 집합을 높이가 높은 집합에 연결하여 트리의 균형을 유지합니다.
3. 디스조인트 집합의 시간 복잡도
위 두 가지 최적화 기법을 사용하면 각 연산의 시간 복잡도는 거의 상수 시간에 가깝습니다:
- Find: O(α(n)), 여기서 α(n)은 아커만 함수의 역함수로 매우 느리게 증가합니다.
- Union: O(α(n))
4. C#으로 디스조인트 집합 구현
다음은 C#을 사용하여 디스조인트 집합을 구현한 코드입니다:
using System;
public class DisjointSet
{
private int[] parent; // 부모 노드 배열
private int[] rank; // 트리의 높이를 저장하는 배열
// 생성자: 각 원소가 자기 자신을 부모로 가지는 초기 상태 설정
public DisjointSet(int size)
{
parent = new int[size];
rank = new int[size];
for (int i = 0; i < size; i++)
{
parent[i] = i; // 자기 자신을 부모로 초기화
rank[i] = 0; // 초기 랭크는 0
}
}
// Find: 원소 x가 속한 집합의 대표 원소를 찾음 (경로 압축 적용)
public int Find(int x)
{
if (parent[x] != x)
{
parent[x] = Find(parent[x]); // 경로 압축
}
return parent[x];
}
// Union: 두 집합을 결합 (랭크 기반 합치기 적용)
public void Union(int x, int y)
{
int rootX = Find(x);
int rootY = Find(y);
if (rootX != rootY)
{
// 랭크 비교 후 결합
if (rank[rootX] > rank[rootY])
{
parent[rootY] = rootX;
}
else if (rank[rootX] < rank[rootY])
{
parent[rootX] = rootY;
}
else
{
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
}
// 사용 예제
public class Program
{
public static void Main()
{
DisjointSet ds = new DisjointSet(5);
ds.Union(0, 1);
ds.Union(1, 2);
Console.WriteLine(ds.Find(0)); // 출력: 0
Console.WriteLine(ds.Find(1)); // 출력: 0
Console.WriteLine(ds.Find(2)); // 출력: 0
Console.WriteLine(ds.Find(3)); // 출력: 3
ds.Union(3, 4);
Console.WriteLine(ds.Find(4)); // 출력: 3
}
}
5. 디스조인트 집합의 활용 사례
5.1 최소 신장 트리 (MST)
- 크루스칼 알고리즘에서 간선 연결 시 두 정점이 같은 집합에 속해 있는지 확인하는 데 사용됩니다.
5.2 연결된 컴포넌트
- 그래프에서 연결된 컴포넌트를 찾는 데 활용됩니다.
5.3 네트워크 연결 확인
- 컴퓨터 네트워크에서 두 장치가 연결되어 있는지 확인합니다.
5.4 친구 관계 문제
- 소셜 네트워크에서 친구 그룹을 관리하거나 연결성을 확인하는 데 유용합니다.
6. 디스조인트 집합의 장단점
장점
- 효율적인 연산: O(α(n))로 매우 빠른 속도 제공.
- 다양한 그래프 알고리즘에서 필수적.
단점
- 초기 구현이 복잡할 수 있음.
- 응용에 따라 최적화가 필요.
디스조인트 집합은 그래프 알고리즘과 집합 관리 문제에서 매우 중요한 자료구조입니다.
특히 최소 신장 트리, 네트워크 연결 확인, 친구 관계 관리 등 다양한 문제를 효율적으로 해결하는 데 사용됩니다.
'Data Structure' 카테고리의 다른 글
트라이 (Trie)의 개념 및 구현 (0) | 2024.11.22 |
---|---|
힙(Heap)의 개념 및 구현 (0) | 2024.11.22 |
해싱과 해시 함수의 개념 및 구현 (1) | 2024.11.22 |
해시 테이블 (Hash Table)의 개념 및 구현 (0) | 2024.11.22 |
인접 리스트, 인접 행렬 표현법 (0) | 2024.11.21 |