Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- kt 에이블스쿨 6기 빅프로젝트
- 케이티 에이블스쿨 기자단
- 백준
- 구현
- 케이티 에이블스쿨 6기 java
- 에이블 기자단
- 앙상블
- ElasticSearch
- 케이티 에이블스쿨
- SQLD
- 엘라스틱서치
- 머신러닝
- kt aivle school
- 판다스
- 네트워크
- 프로그래머스
- 파이썬
- 오블완
- KT 에이블스쿨
- 케이티 에이블스쿨 6기 ai
- kt 에이블스쿨 기자단
- kt 에이블스쿨 6기 미니 프로젝트
- kt 에이블스쿨 6기 ai
- KT AIVLE
- 알고리즘
- 데이터 프레임
- 티스토리챌린지
- 케이티 에이블스쿨 6기 후기
- 케이티 에이블스쿨 6기
- kt 에이블스쿨 6기
Archives
- Today
- Total
미식가의 개발 일기
[알고리즘] 유니온 파인드(Union-Find) 본문
유니온 파인드(Union-Find) 알고리즘이란?
"서로소 집합(Disjoint Set)을 효율적으로 관리하는 자료구조"
[서로소 집합: 공통 원소가 없는 집합]
"두 원소가 같은 집합에 속해 있는지 확인하고, 두 집합을 합치는 작업을 빠르게 수행한다."
주요 연산
1. Find(찾기)
- 어떤 원소가 속한 집단의 대표 원소(루트)를 찾는다.
- 두 원소가 같은 집단에 속해 있는지 확인할 수 있다.
2. Union(합치기)
- 두 집합의 루트를 찾아 하나의 집합으로 합친다.
-> 이 2가지 기법만 가지고 구현하면 트리의 깊이가 깊어질 수 있다. 매번 한 트리의 루트에 다른 트리를 연결하면 트리의 높이가 증가하여 Find 연산이 비효율적으로 수행되므로 최적화 기법이 필요하다.
최적화 기법
1. 경로 압축(Path Compression): Find 연산을 할 때 모든 노드를 루트 노드와 직접 연결
-> 트리의 높이 축소-> 다음 Find 연산을 수행할 때 더욱 빠르게 루트 도달 가능


def find(parent, x):
if parent[x] != x:
parent[x] = find(parent, parent[x])
return parent[x]
2. 랭크 최적화(Union by Rank): Union 연산을 할 때 트리의 높이가 더 낮은 트리를 높은 트리에 붙인다.
-> 트리 높이의 최소화로 더 효율적인 Find 연산 가능
def union(parent, rank, a, b):
rootA = find(parent, a)
rootB = find(parent, b)
# 두 루트가 다르다면 두 집합을 합쳐야 한다.
if rootA != rootB:
# A 트리의 높이가 더 크다면 A루트 밑으로
if rank[rootA] > rank[rootB]:
parent[rootB] = rootA
# B 트리의 높이가 더 크다면 B루트 밑으로
elif rank[rootA] < rank[rootB]:
parent[rootA] = rootB
# 높이가 같은 경우 B를 A에 합침
else:
parent[rootB] = rootA
rank[rootA] += 1 # A 트리의 높이 +1
동작 과정
1. 각 원소는 자기 자신을 부모로 가지는 트리 형태로 시작한다.
2. 두 집합의 루트를 찾고, 랭크에 따라 더 작은 트리를 큰 트리에 합친다.
구현
class UnionFind:
def __init__(self, n):
self.parent = [i for i in range(n)] # 각 노드의 부모를 자기 자신으로 초기화
self.rank = [0] * n # 각 노드의 랭크(트리의 높이)를 0으로 초기화
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
if self.rank[rootX] > self.rank[rootY]:
self.parent[rootY] = rootX
elif self.rank[rootX] < self.rank[rootY]:
self.parent[rootX] = rootY
else:
self.parent[rootY] = rootX
self.rank[rootX] += 1
반응형
'Python > Algorithm' 카테고리의 다른 글
| [백준/Python] #6064번 카잉 달력 (1) | 2024.12.08 |
|---|---|
| [백준/Python] #1107번 리모컨 (1) | 2024.12.05 |
| [백준/Python] #3085번 사탕 게임 (1) | 2024.11.29 |
| [알고리즘] 우선순위 큐를 이용한 다익스트라(Dijkstra), 최단 경로 찾기 (1) | 2024.10.01 |
| [알고리즘] 최소 신장 트리(MST) - 크루스칼, 프림 (0) | 2024.09.26 |