You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
46 lines
1.6 KiB
Go
46 lines
1.6 KiB
Go
package algo
|
|
|
|
type Subset[T comparable] struct {
|
|
Parent T
|
|
Rank int
|
|
}
|
|
|
|
// find is a recursive function that finds the root of the subset that element 'e' belongs to.
|
|
// It uses path compression technique to optimize future find operations.
|
|
// The subsets parameter is a map that stores the subsets with their parent information.
|
|
// The e parameter is the element for which the root is to be found.
|
|
// The function returns the root of the subset that 'e' belongs to.
|
|
// see https://ondrej-kvasnovsky-2.gitbook.io/algorithms/finding/union-find-algorithms
|
|
// or https://jojozhuang.github.io/algorithm/algorithm-union-find/
|
|
func Find[T comparable](subsets map[T]*Subset[T], e T) T {
|
|
// find root and make root as parent of e
|
|
// (path compression)
|
|
if subsets[e].Parent != e {
|
|
subsets[e].Parent = Find(subsets, subsets[e].Parent)
|
|
}
|
|
return subsets[e].Parent
|
|
}
|
|
|
|
// Union merges two subsets in the union-find data structure.
|
|
// It takes a map of subsets, and the names of the two subsets to be merged.
|
|
// The function finds the root of each subset and performs the union operation based on the rank of the subsets.
|
|
func Union[T comparable](subsets map[T]*Subset[T], x, y T) {
|
|
xroot := Find(subsets, x)
|
|
yroot := Find(subsets, y)
|
|
|
|
// Attach smaller rank tree under root of high
|
|
// rank tree (Union by Rank)
|
|
if subsets[xroot].Rank < subsets[yroot].Rank {
|
|
subsets[xroot].Parent = yroot
|
|
} else {
|
|
if subsets[xroot].Rank > subsets[yroot].Rank {
|
|
subsets[yroot].Parent = xroot
|
|
} else {
|
|
// If ranks are same, then make one as root and
|
|
// increment its rank by one
|
|
subsets[yroot].Parent = xroot
|
|
subsets[xroot].Rank++
|
|
}
|
|
}
|
|
}
|