ਇੱਕ disjoint-set (union-find) ਤੱਤਾਂ ਨੂੰ ਗੈਰ-ਓਵਰਲੈਪਿੰਗ ਗਰੁੱਪਾਂ ਵਿੱਚ ਵੰਡਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ "ਕੀ ਇਹ ਦੋ ਇੱਕੋ ਗਰੁੱਪ ਵਿੱਚ ਹਨ?" ਅਤੇ "" ਦੇ ਜਵਾਬ ਦਿੰਦਾ ਹੈ । ਅਤੇ ਨਾਲ, ਦੋਨੋਂ ਓਪਰੇਸ਼ਨਜ਼ ਵਿੱਚ ਚਲਦੀਆਂ ਹਨ — ਪ੍ਰਭਾਵੀ ਤੌਰ ਤੇ O(1) (α inverse Ackermann function ਹੈ)।
ਇੱਕ disjoint-set (union-find) ਤੱਤਾਂ ਨੂੰ ਗੈਰ-ਓਵਰਲੈਪਿੰਗ ਗਰੁੱਪਾਂ ਵਿੱਚ ਵੰਡਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ "ਕੀ ਇਹ ਦੋ ਇੱਕੋ ਗਰੁੱਪ ਵਿੱਚ ਹਨ?" ਅਤੇ "" ਦੇ ਜਵਾਬ ਦਿੰਦਾ ਹੈ । ਅਤੇ ਨਾਲ, ਦੋਨੋਂ ਓਪਰੇਸ਼ਨਜ਼ ਵਿੱਚ ਚਲਦੀਆਂ ਹਨ — ਪ੍ਰਭਾਵੀ ਤੌਰ ਤੇ O(1) (α inverse Ackermann function ਹੈ)।
ਹਰੇਕ ਸੈੱਟ ਇੱਕ ਟ੍ਰੀ ਹੈ; root ਸੈੱਟ ਦਾ ਪ੍ਰਸ਼ਤਿਨਿਧ ਹੈ। find ਰੂਟ ਤੱਕ ਜਾਂਦਾ ਹੈ; union ਇੱਕ ਰੂਟ ਨੂੰ ਦੂਜੇ ਦੇ ਅਧੀਨ ਜੋੜਦਾ ਹੈ।
find(x): follow parents to the root
union(a,b): attach the shorter tree under the taller (by rank)
path compression: after find, point nodes DIRECTLY at the root
before: a->b->c->root after: a->root, b->root, c->root
class DSU:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0]*n
def find(self, x): # path compression
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]] # halve path
x = self.parent[x]
return x
def union(self, a, b): # union by rank
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.rank[ra] < self.rank[rb]: ra, rb = rb, ra
self.parent[rb] = ra
if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
return True
| ਓਪਰੇਸ਼ਨ | ਸਮਾਂ (ਦੋਨੋਂ ਅਨੁਕੂਲਨਾਂ ਨਾਲ) |
|---|---|
| find | O(α(n)) ≈ O(1) |
| union | O(α(n)) ≈ O(1) |
Union-find ਗਰੁੱਪਿੰਗ ਅਤੇ ਕਨੈਕਟੀਵਿਟੀ ਦੀਆਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਹੱਲ ਕਰਦਾ ਹੈ ਜੋ ਬਾਕੀ ਤਰਾਂ ਬਾਰ-ਬਾਰ O(n) ਗ੍ਰਾਫ ਟਰੈਵਰਸਲ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ, ਉਨ੍ਹਾਂ ਨੂੰ ਲਗਭਗ O(1) ਪ੍ਰਤੀ ਪੁੱਛਗਿੱਛ ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ।
ਇਹ ਇੱਕ ਮੁੱਖ ਸਾਧਨ ਹੈ ਜਦੋਂ ਤੁਹਾਨੂੰ ਲਗਾਤਾਰ ਸੈੱਟਾਂ ਨੂੰ ਮਿਲਾਣਾ ਅਤੇ ਕਨੈਕਟੀਵਿਟੀ ਜਾਂਚਣੀ ਹੋਵੇ — ਇੱਕ ਅਕਸਰ ਸੀਨੀਅਰ-ਪੱਧਰ ਦੀ ਸਾਖਾਤਕਾਰ ਵਿਸ਼ੋ।