Skip to content

Instantly share code, notes, and snippets.

@cicorias
Forked from artkpv/union_find.py
Created July 14, 2020 00:15
Show Gist options
  • Save cicorias/b203806cc3fd8063e3d83da2cd56459d to your computer and use it in GitHub Desktop.
Save cicorias/b203806cc3fd8063e3d83da2cd56459d to your computer and use it in GitHub Desktop.
Union-Find in Python (weighted, path compression, connected components)
class UnionFind:
"""Weighted quick-union with path compression and connected components.
The original Java implementation is introduced at
https://www.cs.princeton.edu/~rs/AlgsDS07/01UnionFind.pdf
>>> uf = UnionFind(10)
>>> for (p, q) in [(3, 4), (4, 9), (8, 0), (2, 3), (5, 6), (5, 9),
... (7, 3), (4, 8), (6, 1)]:
... uf.union(p, q)
>>> uf._id
[8, 3, 3, 3, 3, 3, 3, 3, 3, 3]
>>> uf.find(0, 1)
True
>>> uf._id
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
"""
def __init__(self, n):
self._id = list(range(n))
self._sz = [1] * n
self.cc = n # connected components
def _root(self, i):
j = i
while (j != self._id[j]):
self._id[j] = self._id[self._id[j]]
j = self._id[j]
return j
def find(self, p, q):
return self._root(p) == self._root(q)
def union(self, p, q):
i = self._root(p)
j = self._root(q)
if i == j:
return
if (self._sz[i] < self._sz[j]):
self._id[i] = j
self._sz[j] += self._sz[i]
else:
self._id[j] = i
self._sz[i] += self._sz[j]
self.cc -= 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment