Disjoint set
Il disjoint set memorizza una collezione di sottoinsiemi disgiunti di un insieme generativo. Ammette operazioni di ricerca e unione, ma non inserzione e cancellazione.
Un insieme generativo è un insieme del tipo . I sottoinsiemi disgiunti sono sottoinsiemi di un insieme generativo, del tipo tale che
Primitive
make-set(X): restituisce un disjoint set in cui -find-set(DS, x): restituisce un rappresentante dell’insieme a cui appartieenx-union(DS, x, y): unisce gli insiemi a cui appartengono x, y -
Ogni insieme è rappresentato da un albero, e quindi per ogni insieme esiste un rappresentante che fa da radice dell’albero.

make-set(X):
DS := new_array[1..n]
for i=1 to n do
DS[i] := 1
return DS
Costo computazionale
find-set(DS, x):
if DS[x] = x then
return x
else
return find-set(DS, DS[x])
Costo computazionale lineare all’altezza dell’albero.
union(DS, x, y):
xr := find-set(DS, x)
yr := find-set(DS, y)
if xr != yr then
DS[xr] := yr
Anche in questo caso il costo computazionale è lineare all’altezza dei due alberi, quindi il costo è di
Rango
Ogni albero ha un rango, che rappresenta la sua altezza. Il Disjoint set, quindi, mantiene un array di rank, e un array di padri.
make-set(X):
DS.p := new_array[1..n]
DS.rank := new_array[1..n]
for i=1 to n do
DS.p[i] := 1
DS.rank := 0
return DS
find-set(DS, x):
if DS.p[x] = x then
return x
else
return find-set(DS, DS[x])
union(DS, x, y):
xr := find-set(DS, x)
yr := find-set(DS, y)
if xr != yr then
if DS.rank[xr] > DS.rank[yr] then
DS.p[yr] := xr
else
DS.p[xr] := yr
if DS.rank[xr] = DS.rank[yr] then
DS.rank[yr] := DS.rank[yr] + 1
Utilizzando l’euristica del rango, un albero della foresta con radice r ha almeno nodi, quindi un albero di radice r con k nodi ha
Il costo computazionale di find e union, usando il rango, è di .
Perchè?
Caso base: subito dopo make-set, prima della union si ha
- ogni albero ha esattamente un nodo
- per ogni nodo
rsi harank[r] = 0
Ipotesi induttiva: dopo operazioni union, per un albero di nodi con rappresentante r vale che .
Per xr = yr è vero.
Se invece xr != yr, allora
rank[xr] > rank[yr]:xrdiventa il rappresentante diyr, ma il rango no cambiarank[xr] < rank[yr]:yrdiventa il rappresentante dixr, ma il rango no cambiarank[xr] = rank[yr]:make-setcosta sempre , mentreunionefind-setcostano