blob: dd2da2562366f522ca2ca62df3a42c3529b1cea5 [file] [log] [blame]
Graydon Hoarece729932011-06-15 18:19:501
Marijn Haverbeke3816e572011-05-12 15:24:542import option::none;
3import option::some;
Patrick Waltonafa6d852011-04-08 01:01:214
Graydon Hoarece729932011-06-15 18:19:505
Patrick Waltonafa6d852011-04-08 01:01:216// A very naive implementation of union-find with unsigned integer nodes.
Patrick Walton4eb476f2011-05-20 22:46:017// Maintains the invariant that the root of a node is always equal to or less
8// than the node itself.
Marijn Haverbeke3816e572011-05-12 15:24:549type node = option::t[uint];
Graydon Hoarece729932011-06-15 18:19:5010
Marijn Haverbekedf7f21d2011-07-27 12:19:3911type ufind = {mutable nodes: vec[mutable node]};
Patrick Waltonafa6d852011-04-08 01:01:2112
Marijn Haverbekedf7f21d2011-07-27 12:19:3913fn make() -> ufind { ret {mutable nodes: [mutable ]}; }
Patrick Waltonafa6d852011-04-08 01:01:2114
Marijn Haverbekedf7f21d2011-07-27 12:19:3915fn make_set(ufnd: &ufind) -> uint {
16 let idx = vec::len(ufnd.nodes);
Graydon Hoarefbbc1a72011-05-17 01:21:2217 ufnd.nodes += [mutable none[uint]];
Patrick Waltonec5a60d2011-04-08 21:53:1618 ret idx;
Patrick Waltonafa6d852011-04-08 01:01:2119}
20
Graydon Hoarece729932011-06-15 18:19:5021
Patrick Waltonddec6b52011-05-21 01:36:3522/// Creates sets as necessary to ensure that least `n` sets are present in the
23/// data structure.
Marijn Haverbekedf7f21d2011-07-27 12:19:3924fn grow(ufnd: &ufind, n: uint) {
25 while set_count(ufnd) < n { make_set(ufnd); }
Patrick Waltonddec6b52011-05-21 01:36:3526}
27
Marijn Haverbekedf7f21d2011-07-27 12:19:3928fn find(ufnd: &ufind, n: uint) -> uint {
29 alt ufnd.nodes.(n) {
30 none. { ret n; }
31 some(m) { let m_ = m; be find(ufnd, m_); }
Patrick Waltonafa6d852011-04-08 01:01:2132 }
33}
34
Marijn Haverbekedf7f21d2011-07-27 12:19:3935fn union(ufnd: &ufind, m: uint, n: uint) {
36 let m_root = find(ufnd, m);
37 let n_root = find(ufnd, n);
38 if m_root < n_root {
Patrick Walton4eb476f2011-05-20 22:46:0139 ufnd.nodes.(n_root) = some[uint](m_root);
Graydon Hoarece729932011-06-15 18:19:5040 } else if (m_root > n_root) { ufnd.nodes.(m_root) = some[uint](n_root); }
Patrick Walton4eb476f2011-05-20 22:46:0141}
42
Marijn Haverbekedf7f21d2011-07-27 12:19:3943fn set_count(ufnd: &ufind) -> uint { ret vec::len[node](ufnd.nodes); }
Graydon Hoarece729932011-06-15 18:19:5044
Patrick Waltonddec6b52011-05-21 01:36:3545
Patrick Walton4eb476f2011-05-20 22:46:0146// Removes all sets with IDs greater than or equal to the given value.
Marijn Haverbekedf7f21d2011-07-27 12:19:3947fn prune(ufnd: &ufind, n: uint) {
Patrick Walton4eb476f2011-05-20 22:46:0148 // TODO: Use "slice" once we get rid of "mutable?"
Patrick Waltonafa6d852011-04-08 01:01:2149
Marijn Haverbekedf7f21d2011-07-27 12:19:3950 let len = vec::len[node](ufnd.nodes);
51 while len != n { vec::pop[node](ufnd.nodes); len -= 1u; }
52}