70 lines
1.5 KiB
Common Lisp
70 lines
1.5 KiB
Common Lisp
//! Disjoint Set Forest implementation of the Union Find algorithm
|
|
|
|
// enum TreeNode {
|
|
// Empty,
|
|
// Filled { parent: usize, rank: usize }
|
|
// }
|
|
|
|
// TODO: Namespace based on type of first argument
|
|
|
|
fn makeset(f, x) {
|
|
match (*f)[x] {
|
|
() => (*f)[x] = Filled { parent: x, rank: 0 },
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn union(f, a, b) {
|
|
let (a, b) = (find(f, a), find(f, b));
|
|
if a == b { return; }
|
|
match ((*f)[a], (*f)[b]) {
|
|
(Filled {parent: _, rank: r_a}, Filled {parent: _, rank: r_b}) => {
|
|
if r_a < r_b {
|
|
union(f, b, a)
|
|
} else {
|
|
(*f)[b].parent = a;
|
|
(*f)[a].rank += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn find(f, x) {
|
|
match (*f)[x] {
|
|
Filled { parent, rank } => if parent == x {
|
|
x
|
|
} else {
|
|
let parent = find(f, parent);
|
|
(*f)[x].parent = parent;
|
|
parent
|
|
},
|
|
() => x,
|
|
}
|
|
}
|
|
|
|
fn show(f) {
|
|
for node in 0..(len((*f))) {
|
|
match (*f)[node] {
|
|
Filled { parent, rank } => println(node, ": { parent: ", parent, ", rank: ", rank, " }"),
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn test(f) {
|
|
"Union Find on Disjoint Set Forest".println()
|
|
for i in 0..10 { makeset(f, i) }
|
|
for i in 10..20 { makeset(f, i) }
|
|
show(f)
|
|
println()
|
|
|
|
for i in 1..10 { union(f, i*2-1, i*2) }
|
|
for i in 5..10 { union(f, i*2+1, i*2) }
|
|
show(f)
|
|
}
|
|
|
|
fn main() {
|
|
let f = [();20]
|
|
f.test()
|
|
}
|