1
+ /*
2
+ ************Union-Find/ Disjoint-Set Data Structure************
3
+ Based on explanation from Page No. 98 to 103 and also from https://bit.ly/337fmv1
4
+ particularly used path compression technique while implementing
5
+ Direct URL for above Shortened URL: https://opendsa-server.cs.vt.edu/ODSA/Books/Everything/html/UnionFind.html
6
+ For Complexities of these operations, refer to Pg. No. 96
7
+ ***************************************************************
8
+
9
+ Usage:
10
+ import this "unionds" package in Go main file
11
+
12
+ Initialize Union-Find Data Structure:
13
+ Syntax: Initialize(vertices ...string) Partition {...}
14
+ Ex: uds := Initialize("1", "2", "3", "4", "5", "6")
15
+ Output: Partition{P: []Node{[{1 0 1} {2 1 1} {3 2 1} {4 3 1} {5 4 1} {6 5 1}]}
16
+ Index: map[1:0 2:1 3:2 4:3 5:4 6:5]}
17
+ Finding to which set in the partition the given key belongs to:
18
+ Given a key, it returns the parent of the set this key belongs to
19
+ Syntax: uds.Find(key string) int {...}
20
+ Ex: uds.Find("5") -> key "5" belongs to a set whose parent is 4, so it returns 4
21
+ Combine two sets by giving any of the keys in those sets using Union() method
22
+ Given two keys, it searches for the sets to which these two keys belongs to and merge these two sets
23
+ Syntax: uds.UnionUnion(key1, key2 string)
24
+ Ex:
25
+ Step 1: uds := Initialize("1", "2", "3", "4", "5", "6")
26
+ Output: Partition{P: []Node{[{1 0 1} {2 1 1} {3 2 1} {4 3 1} {5 4 1} {6 5 1}]}
27
+ Index: map[1:0 2:1 3:2 4:3 5:4 6:5]}
28
+ Step 2: uds.Union("5", "6")
29
+ Output: Partition{P: []Node{[{1 0 1} {2 1 1} {3 2 1} {4 3 1} {5 4 1} {6 4 1}]}
30
+ Index: map[1:0 2:1 3:2 4:3 5:4 6:5]}
31
+ The sets of those two keys "5", "6" are merged. Now key "6" parent is "5" thus they both are
32
+ linked together as a single set
33
+ */
34
+
35
+
36
+
37
+
38
+ package unionds
39
+
40
+ import (
41
+ "fmt"
42
+ )
43
+
44
+
45
+ type Node struct {
46
+ N string // Name of the node N
47
+ P int // Parent's Index P
48
+ S int // Size S
49
+ }
50
+
51
+ type Partition struct {
52
+ P []Node // Parition P
53
+ Index map [string ]int // Map for index of each node's name N
54
+ }
55
+
56
+ func Initialize (vertices ... string ) Partition {
57
+ slice := Partition {P :[]Node {}, Index :map [string ]int {}}
58
+ for _ , vertex := range vertices {
59
+ slice .P = append (slice .P , Node {vertex , len (slice .P ), 1 })
60
+ slice .Index [vertex ] = len (slice .P )- 1
61
+ }
62
+ return slice
63
+ }
64
+
65
+
66
+ func (p * Partition ) Find (key string ) int {
67
+ idx := p .Index [key ]
68
+ for p .P [idx ].P != idx {
69
+ idx = p .P [idx ].P
70
+ }
71
+ return p .P [idx ].P
72
+ }
73
+
74
+ func (p * Partition ) Union (key1 , key2 string ) {
75
+ root1Idx := p .Find (key1 )
76
+ root2Idx := p .Find (key2 )
77
+ if root1Idx != root2Idx {
78
+ if p .P [root1Idx ].S >= p .P [root2Idx ].S {
79
+ p .P [root2Idx ].P = root1Idx
80
+ p .P [root1Idx ].S += p .P [root2Idx ].S
81
+ } else {
82
+ p .P [root1Idx ].P = root2Idx
83
+ p .P [root2Idx ].S += p .P [root1Idx ].S
84
+ }
85
+ }
86
+ }
87
+
88
+
89
+ func (p * Partition ) Show () {
90
+ fmt .Println (p .P )
91
+ }
0 commit comments