public class DisjointSetElement {
private DisjointSetElement representative = this;
public DisjointSetElement getRepresentative() {
if (representative != this) {
representative = representative.getRepresentative();
}
return representative;
}
public void union(DisjointSetElement other) {
other.getRepresentative().representative = getRepresentative();
}
}
(defstruct disjoint-set
elements)
(defun make-disjoint-set (elements)
(make-disjoint-set :elements elements))
(defun partition (disjoint-set)
(loop for element in (disjoint-set-elements disjoint-set)
collect
(let ((found (find element (mapcar #'first (rest disjoint-set))
:test #'equal)))
(if found
(acons element element found :test #'equal)
(acons element element nil :test #'equal)))))
my @vert = (1..5);
my @edges = ( [1, 2], [2, 3], [4, 5] );
$uf->add( $_ ) for @vert;
$uf->union( $_ ) for @edges;
# find and consolidate partitions into a hash
my %part;
foreach my $v( @vert ) {
my @pa = $uf->find($v);
my $p = shift @pa;
$part{$p} //= [];
push @{ $part{$p} }, $v;
}
foreach my $k (sort keys %part) {
my $vals = join ' ', @{ $part{$k} };
say "$k : $vals";
}
# prints:
# 2 : 1 2 3
# 5 : 4 5
class UnionFind:
def __init__(self, size):
self.rank = [0] * size
self.p = [i for i in range(size)]
def find_set(self, i):
if self.p[i] == i:
return i
else:
self.p[i] = self.find_set(self.p[i])
return self.p[i]
def is_same_set(self, i, j):
return self.find_set(i) == self.find_set(j)
def union_set(self, i, j):
if not self.is_same_set(i, j):
x, y = self.find_set(i), self.find_set(j)
public class DisjointSetElement { private DisjointSetElement representative = this; public DisjointSetElement getRepresentative() { if (representative != this) { representative = representative.getRepresentative(); } return representative; } public void union(DisjointSetElement other) { other.getRepresentative().representative = getRepresentative(); } }
(defstruct disjoint-set elements) (defun make-disjoint-set (elements) (make-disjoint-set :elements elements)) (defun partition (disjoint-set) (loop for element in (disjoint-set-elements disjoint-set) collect (let ((found (find element (mapcar #'first (rest disjoint-set)) :test #'equal))) (if found (acons element element found :test #'equal) (acons element element nil :test #'equal)))))
my @vert = (1..5); my @edges = ( [1, 2], [2, 3], [4, 5] ); $uf->add( $_ ) for @vert; $uf->union( $_ ) for @edges; # find and consolidate partitions into a hash my %part; foreach my $v( @vert ) { my @pa = $uf->find($v); my $p = shift @pa; $part{$p} //= []; push @{ $part{$p} }, $v; } foreach my $k (sort keys %part) { my $vals = join ' ', @{ $part{$k} }; say "$k : $vals"; } # prints: # 2 : 1 2 3 # 5 : 4 5
class UnionFind: def __init__(self, size): self.rank = [0] * size self.p = [i for i in range(size)] def find_set(self, i): if self.p[i] == i: return i else: self.p[i] = self.find_set(self.p[i]) return self.p[i] def is_same_set(self, i, j): return self.find_set(i) == self.find_set(j) def union_set(self, i, j): if not self.is_same_set(i, j): x, y = self.find_set(i), self.find_set(j)
a.disjoint?(b)