Paste: sadfa
Author: | erikc |
Mode: | c |
Date: | Thu, 6 Jan 2011 07:37:17 |
Plain Text |
private record Cell[T](value : T,
rank : SizeT,
parent : Pointer[Cell[T]]);
[T]
overload Cell[T](v : T) {
return Cell[T](v, SizeT(0), null(Cell[T]));
}
[T]
overload hash(c : Cell[T]) {
return hash(c.value);
}
[T]
overload equals?(lhs : Cell[T], rhs : Cell[T]) {
return equals?(lhs.value, rhs.value);
}
record DisjointSet[T](hash : HashMap[T, Cell[T]]);
[T]
private compress_path(c : Cell[T]) ByRef[Cell[T]] {
if (null?(c.parent))
return ref c;
c.parent <-- &compress_path(c.parent^);
return ref c.parent^;
}
[T]
overload put(dj : DisjointSet[T], t : T) {
put(dj.hash, t, Cell[T](t));
}
[T]
merge(dj : DisjointSet[T], t1 : T, t2 : T) {
var i = lookup(dj.hash, t1);
if (null?(i))
return false;
var j = lookup(dj.hash, t2);
if (null?(j))
return false;
println("MERGE1 ", i, " ", j);
var set_i = compress_path(i^);
var set_j = compress_path(j^);
if (&set_i == &set_j)
return false;
if (set_i.rank > set_j.rank)
set_j.parent = &set_i;
else {
set_i.parent = &set_j;
println("MERGE ", set_i.parent, " ", &set_j);
if (set_i.rank == set_j.rank)
set_j.rank <-- set_j.rank + 1;
}
return true;
}
[T]
overload lookup(dj : DisjointSet[T], t : T) {
var i = lookup(dj.hash, t);
if (null?(i))
return null(T);
else
return &compress_path(i^).value;
}
[T]
same_set(dj : DisjointSet[T], t1 : T, t2 : T) {
var i = lookup(dj.hash, t1);
if (null?(i))
return false;
var j = lookup(dj.hash, t2);
if (null?(j))
return false;
var set_i = compress_path(i^);
var set_j = compress_path(j^);
println("COMP ", set_i, " ", &set_i, " ", set_j, " ", &set_j);
return &set_i == &set_j;
}
main() {
var ok = Cell[Int32](3);
compress_path(ok);
var dj = DisjointSet[Int32]();
put(dj, 3);
put(dj, 4);
put(dj, 5);
assert(not same_set(dj, 3, 4));
assert(not same_set(dj, 3, 5));
assert(not same_set(dj, 4, 5));
merge(dj, 3, 4);
assert(same_set(dj, 3, 4));
assert(not same_set(dj, 3, 5));
assert(not same_set(dj, 4, 5));
}
New Annotation