Skip to content

Instantly share code, notes, and snippets.

@lavantien
Created March 3, 2022 15:52
Show Gist options
  • Save lavantien/2289412b60f435985fa5885c679e59a1 to your computer and use it in GitHub Desktop.
Save lavantien/2289412b60f435985fa5885c679e59a1 to your computer and use it in GitHub Desktop.
Golang - Optimized Hashmap Tree-based Disjoint Set
package main
import "fmt"
type DisjointSet interface {
Find(item int) int
Union(setA int, setB int)
}
type hashmapDisjointSet struct {
parent map[int]int
rank map[int]int // record the depth of the trees representing the sets
}
// Must implement all
var _ DisjointSet = (*hashmapDisjointSet)(nil)
func NewHashmapDisjointSet(universe []int) DisjointSet {
m := make(map[int]int)
r := make(map[int]int)
for _, c := range universe {
m[c] = c
r[c] = 0
}
// We have len(universe) disjoint sets, each set cointain one item, hence its parent is itself
// Hardcode some init state, the first set and last set in the universe will be in the same set now
m[universe[0]] = universe[len(universe)-1]
r[universe[len(universe)-1]] = 1
return &hashmapDisjointSet{
parent: m,
rank: r,
}
}
func (s *hashmapDisjointSet) Find(item int) int {
if s.parent[item] == item {
return item
}
return s.Find(s.parent[item])
}
func (s *hashmapDisjointSet) Union(setA int, setB int) {
if s.rank[setA] > s.rank[setB] {
s.parent[setB] = setA
} else if s.rank[setB] > s.rank[setA] {
s.parent[setA] = setB
} else {
s.parent[setA] = setB
s.rank[setB]++
}
}
func main() {
universe := []int{1, 2, 3, 4, 5}
ds := NewHashmapDisjointSet(universe)
a := ds.Find(2) // returns 2
ds.Union(2, 3) // 2 and 3 now in the same set 3
b := ds.Find(2) // returns 3
ds.Union(3, 5) // 1, 2, 3, and 5 now in the same set 5
c := ds.Find(2) // returns 5
fmt.Println(a, b, c)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment