Computer Science

Union-Find

Balang 2025. 4. 17. 12:00
728x90

Union-Find란?

여러 개의 원소가 있을 때,어떤 원소가 어떤 집합에 속해 있는지 빠르게 알 수 있도록 해주는 자료구조입니다.
  • Find: 어떤 원소가 어느 집합에 속해 있는지 찾기
  • Union: 두 집합을 하나로 합치기

어떤 상황에서 쓰일까?

  • 그래프의 사이클 판별
  • 크루스칼 알고리즘 (최소 신장 트리)
  • 네트워크 연결 여부 판단
  • 집합의 묶음 관리

기본 구현 (Python)

# 1. 자기 자신을 부모로 초기화
parent = [i for i in range(10)]

# 2. Find 함수 (재귀)
def find(x):
    if parent[x] != x:
        return find(parent[x])
    return x

# 3. Union 함수
def union(x, y):
    root_x = find(x)
    root_y = find(y)
    if root_x != root_y:
        parent[root_y] = root_x

경로 압축 (Path Compression)

Find 연산 시, 루트를 찾을 때 경로를 압축해서 속도 향상
def find(x):
    if parent[x] != x:
        parent[x] = find(parent[x])  # 경로 압축!
    return parent[x]

Union by Rank (또는 Union by Size)

항상 작은 트리를 큰 트리에 붙여 높이를 최소화
시간복잡도: 거의 O(1)
rank = [0] * 10

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
    else:
        parent[root_y] = root_x
        if rank[root_x] == rank[root_y]:
            rank[root_x] += 1

사이클 판별 예제

def has_cycle(edges, n):
    parent = [i for i in range(n+1)]
    
    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 True  # 사이클 발생
        parent[root_y] = root_x
        return False

    for a, b in edges:
        if union(a, b):
            return True
    return False

항목 설명
자료구조 트리 기반 집합 관리
주요 연산 Find, Union
최적화 Path Compression, Union by Rank
사용 예 싸이클 판별, 크루스칼 알고리즘, 네트워크 그룹핑
시간복잡도 O(α(N)) ≈ O(1) (거의 상수 시간)

 

728x90
반응형