-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathquick_find.go
66 lines (54 loc) · 1.26 KB
/
quick_find.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package uf
// QuickFind Quick-find algorithm.
// It maintains the invariant that p and q are connected if and only if
// id[p] = id[q]. In other words, all sites in a component must have the
// same value in id[]
type QuickFind struct {
id []int // id[i]: component identifier of i
count int // number of components
}
// NewQuickFind returns an empty union-find data structure with n elements (0...n-1)
// Initially, each element is in its own set.
func NewQuickFind(n int) *QuickFind {
id := make([]int, n)
for i := 0; i < n; i++ {
id[i] = i
}
return &QuickFind{id, n}
}
func (qf *QuickFind) Find(p int) int {
qf.validate(p)
return qf.id[p]
}
func (qf *QuickFind) Union(p, q int) {
qf.validate(p)
qf.validate(q)
// needed for correctness to reduce the number of array accesses
pID := qf.id[p]
qID := qf.id[q]
// p and q are already in the same component
if pID == qID {
return
}
n := len(qf.id)
for i := 0; i < n; i++ {
if qf.id[i] == pID {
qf.id[i] = qID
}
}
qf.count--
}
func (qf *QuickFind) Count() int {
return qf.count
}
func (qf *QuickFind) Connected(p, q int) bool {
qf.validate(p)
qf.validate(q)
return qf.id[p] == qf.id[q]
}
func (qf *QuickFind) validate(p int) {
n := len(qf.id)
if p < 0 || p >= n {
panic("invalid index")
}
}