1 //! `UnionFind<K>` is a disjoint-set data structure.
3 use super::graph
::IndexType
;
5 /// `UnionFind<K>` is a disjoint-set data structure. It tracks set membership of *n* elements
6 /// indexed from *0* to *n - 1*. The scalar type is `K` which must be an unsigned integer type.
8 /// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>
10 /// Too awesome not to quote:
12 /// “The amortized time per operation is **O(α(n))** where **α(n)** is the
13 /// inverse of **f(x) = A(x, x)** with **A** being the extremely fast-growing Ackermann function.”
14 #[derive(Debug, Clone)]
15 pub struct UnionFind
<K
>
17 // For element at index *i*, store the index of its parent; the representative itself
18 // stores its own index. This forms equivalence classes which are the disjoint sets, each
19 // with a unique representative.
21 // It is a balancing tree structure,
22 // so the ranks are logarithmic in the size of the container -- a byte is more than enough.
24 // Rank is separated out both to save space and to save cache in when searching in the parent
30 unsafe fn get_unchecked
<K
>(xs
: &[K
], index
: usize) -> &K
32 debug_assert
!(index
< xs
.len());
33 xs
.get_unchecked(index
)
39 /// Create a new `UnionFind` of `n` disjoint sets.
40 pub fn new(n
: usize) -> Self
42 let rank
= vec
![0; n
];
43 let parent
= (0..n
).map(K
::new
).collect
::<Vec
<K
>>();
45 UnionFind{parent: parent, rank: rank}
48 /// Return the representative for `x`.
50 /// **Panics** if `x` is out of bounds.
51 pub fn find(&self, x
: K
) -> K
53 assert
!(x
.index() < self.parent
.len());
57 // Use unchecked indexing because we can trust the internal set ids.
58 let xparent
= *get_unchecked(&self.parent
, x
.index());
68 /// Return the representative for `x`.
70 /// Write back the found representative, flattening the internal
71 /// datastructure in the process and quicken future lookups.
73 /// **Panics** if `x` is out of bounds.
74 pub fn find_mut(&mut self, x
: K
) -> K
76 assert
!(x
.index() < self.parent
.len());
78 self.find_mut_recursive(x
)
82 unsafe fn find_mut_recursive(&mut self, x
: K
) -> K
84 let xparent
= *get_unchecked(&self.parent
, x
.index());
86 let xrep
= self.find_mut_recursive(xparent
);
87 let xparent
= self.parent
.get_unchecked_mut(x
.index());
96 /// Unify the two sets containing `x` and `y`.
98 /// Return `false` if the sets were already the same, `true` if they were unified.
100 /// **Panics** if `x` or `y` is out of bounds.
101 pub fn union(&mut self, x
: K
, y
: K
) -> bool
106 let xrep
= self.find_mut(x
);
107 let yrep
= self.find_mut(y
);
113 let xrepu
= xrep
.index();
114 let yrepu
= yrep
.index();
115 let xrank
= self.rank
[xrepu
];
116 let yrank
= self.rank
[yrepu
];
118 // The rank corresponds roughly to the depth of the treeset, so put the
119 // smaller set below the larger
121 self.parent
[xrepu
] = yrep
;
122 } else if xrank
> yrank
{
123 self.parent
[yrepu
] = xrep
;
125 // put y below x when equal.
126 self.parent
[yrepu
] = xrep
;
127 self.rank
[xrepu
] += 1;
132 /// Return a vector mapping each element to its representative.
133 pub fn into_labeling(mut self) -> Vec
<K
>
135 // write in the labeling of each element
137 for ix
in 0..self.parent
.len() {
138 let k
= *get_unchecked(&self.parent
, ix
);
139 let xrep
= self.find_mut_recursive(k
);
140 *self.parent
.get_unchecked_mut(ix
) = xrep
;