유니온 파인드 랭크 기반 병합
유니온 파인드 랭크 기반 병합(Union-Find with Union by Rank)은 병합-찾기 자료구조에서 두 집합을 병합할 때 트리의 높이를 최소화하여 성능을 최적화하는 기법이다.
1 개요[편집 | 원본 편집]
랭크 기반 병합은 유니온 파인드(상호 배타적 집합 자료구조)의 핵심 최적화 기법 중 하나로, 집합 병합 시 트리 구조의 불균형을 방지하기 위해 사용된다. 각 집합은 트리 형태로 표현되며, 트리의 깊이를 추정하는 랭크(rank)를 기반으로 병합 순서를 결정한다.
일반적으로 랭크는 트리의 실제 높이를 나타내기보다는 상대적인 깊이 수준을 나타내는 수치로 사용된다.
2 랭크의 기준[편집 | 원본 편집]
랭크는 각 트리의 루트 노드에 부여되는 정수 값으로, 해당 트리가 어느 정도 깊이를 갖고 있는지를 근사적으로 나타낸다. 초기에 모든 원소는 자신이 루트인 깊이 0의 트리이므로 랭크는 0으로 시작한다. 두 트리를 병합할 때, 랭크가 더 낮은 트리를 더 높은 트리에 붙이고, 두 트리의 랭크가 같다면 한쪽을 다른 쪽에 병합한 후 병합된 트리의 랭크를 1 증가시킨다. 이 방식은 트리의 깊이를 가능한 한 최소로 유지하며, Find 연산의 효율을 극대화한다. 실제로 랭크는 트리의 실질적 깊이를 정확히 반영하지 않지만, 병합 순서를 결정하기 위한 기준으로 충분히 유효하다.
3 원리[편집 | 원본 편집]
- 각 원소는 자기 자신을 루트로 하는 독립적인 트리에서 시작하며, 모든 원소는 parent 배열로 부모 노드를 저장한다.
- 각 집합의 루트 노드는 랭크 정보를 함께 가지고 있다. 이는 일반적으로 별도의 rank 배열에 저장된다.
- Union 연산 시 두 집합의 루트를 비교하고, 랭크가 더 작은 트리를 더 큰 트리에 병합한다.
- 만약 두 루트의 랭크가 동일하다면, 둘 중 하나를 다른 쪽의 자식으로 만들고 병합된 트리의 랭크를 1 증가시킨다.
4 구현 예시[편집 | 원본 편집]
다음은 랭크 기반 병합을 포함한 유니온 파인드의 기본 구조이다:
def find(x):
if parent[x] != x:
parent[x] = find(parent[x]) # 경로 압축
return parent[x]
def union(x, y):
root_x = find(x)
root_y = find(y)
if root_x == root_y:
return
if rank[root_x] < rank[root_y]:
parent[root_x] = root_y
elif rank[root_x] > rank[root_y]:
parent[root_y] = root_x
else:
parent[root_y] = root_x
rank[root_x] += 1
5 시간 복잡도[편집 | 원본 편집]
랭크 기반 병합과 경로 압축을 함께 사용할 경우, 유니온 파인드 자료구조의 모든 연산의 평균 시간 복잡도는 O(α(n))이 된다. 여기서 α(n)은 아커만 함수의 역함수로, 실용적인 모든 입력 크기에 대해 상수에 가까운 값을 갖는다.
6 장점[편집 | 원본 편집]
- 트리의 높이를 제한하여 Find 연산의 시간 복잡도를 낮춘다.
- 구조적 균형을 유지하므로 대량의 Union 및 Find 연산이 반복되는 알고리즘에서 매우 효과적이다.
- Kruskal 알고리즘 등 그래프 기반 알고리즘에서 성능 향상에 결정적이다.
7 같이 보기[편집 | 원본 편집]
8 참고 문헌[편집 | 원본 편집]
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press.
- Tarjan, R. E. (1975). Efficiency of a Good But Not Linear Set Union Algorithm. Journal of the ACM, 22(2), 215-225.