delaunay/mst working
This commit is contained in:
72
util/uf/uf.go
Normal file
72
util/uf/uf.go
Normal file
@ -0,0 +1,72 @@
|
||||
package uf
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Interface is how you use the union-find data structure.
|
||||
type Interface interface {
|
||||
Find(p int) int
|
||||
Count() int
|
||||
Connected(p, q int) bool
|
||||
Union(p, q int)
|
||||
validate(p int)
|
||||
}
|
||||
|
||||
type instance struct {
|
||||
parent []int
|
||||
rank []byte
|
||||
count int
|
||||
}
|
||||
|
||||
func (i *instance) Find(p int) int {
|
||||
i.validate(p)
|
||||
for p != i.parent[p] {
|
||||
i.parent[p] = i.parent[i.parent[p]]
|
||||
p = i.parent[p]
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (i *instance) Count() int {
|
||||
return i.count
|
||||
}
|
||||
|
||||
func (i *instance) Connected(p, q int) bool {
|
||||
return i.Find(p) == i.Find(q)
|
||||
}
|
||||
|
||||
func (i *instance) Union(p, q int) {
|
||||
rootP := i.Find(p)
|
||||
rootQ := i.Find(q)
|
||||
if rootP == rootQ {
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case i.rank[rootP] < i.rank[rootQ]:
|
||||
i.parent[rootP] = rootQ
|
||||
case i.rank[rootP] > i.rank[rootQ]:
|
||||
i.parent[rootQ] = rootP
|
||||
default:
|
||||
i.parent[rootQ] = rootP
|
||||
i.rank[rootP]++
|
||||
}
|
||||
i.count--
|
||||
}
|
||||
|
||||
func (i *instance) validate(p int) {
|
||||
if n := len(i.parent); p < 0 || p >= n {
|
||||
panic(fmt.Sprintf("index %d is not between 0 and %d", p, n-1))
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new instance of a union-find interface.
|
||||
func New(n int) Interface {
|
||||
created := &instance{
|
||||
parent: make([]int, n),
|
||||
rank: make([]byte, n),
|
||||
count: n,
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
created.parent[i] = i
|
||||
}
|
||||
return created
|
||||
}
|
Reference in New Issue
Block a user