File tree Expand file tree Collapse file tree 6 files changed +205
-0
lines changed
Graphs/UnionFind/DisjointSet Expand file tree Collapse file tree 6 files changed +205
-0
lines changed Original file line number Diff line number Diff line change 1+ # The vey basics of union find and disjoint sets
2+ # Basically an array and within that array lies a disjoint set
3+
4+
5+ # There are two functions when discussing disjoint sets
6+
7+ # find(a) which takes in a single argument and returns the root of
8+ # that particular node
9+
10+ # union(a,b) which takes in two arguments and combines them together
11+ # let's watch a quick video on how this works and then implement from there
12+
13+ # First lets implement UnionFind as an object and instantiate it with an array
14+
15+ class UnionFind :
16+ def __init__ (self , size ):
17+ self .root = [i for i in range (size )]
18+
19+ # union connects two nodes with a left bias meaning that b will always
20+ # connect to a
21+ def union (self , x , y ):
22+ rootX = self .find (x )
23+ rootY = self .find (y )
24+ if rootX != rootY :
25+ for i in range (len (self .root )):
26+ if self .root [i ] == rootY :
27+ self .root [i ] = rootX
28+
29+ # takes in a node a and returns the root node of such
30+ def find (self , a ):
31+ while a != self .root [a ]:
32+ a = self .root [a ]
33+ return a
34+
35+ uu = UnionFind (10 )
36+
37+ print (uu .root )
38+ uu .union (0 ,1 )
39+ uu .union (0 ,2 )
40+ uu .union (1 ,3 )
41+ uu .union (4 ,8 )
42+ uu .union (5 ,6 )
43+ uu .union (5 ,7 )
44+ print (uu .root )
45+ print ([i for i in range (10 )])
Original file line number Diff line number Diff line change 1+
2+ class UnionFind :
3+ def __init__ (self ,size ):
4+ self .root = [i for i in range (size )]
5+
6+ def find (self , n ):
7+ if self .root [n ] == n :
8+ return n
9+
10+ self .root [n ] = self .find (self .root [n ])
11+ return self .root [n ]
12+ # quick union
13+ def union (self , a , b ):
14+ fa = self .find (a )
15+ fb = self .find (b )
16+ if fa != fb :
17+ self .root [fa ] = fb
18+
19+ def connected (self , x , y ):
20+ return self .find (x ) == self .find (y )
21+ # Test Case
22+ uf = UnionFind (10 )
23+ # 1-2-5-6-7 3-8-9 4
24+ uf .union (1 , 2 )
25+ uf .union (2 , 5 )
26+ uf .union (5 , 6 )
27+ uf .union (6 , 7 )
28+ uf .union (3 , 8 )
29+ uf .union (8 , 9 )
30+ print (uf .connected (1 , 5 )) # true
31+ print (uf .connected (5 , 7 )) # true
32+ print (uf .connected (4 , 9 )) # false
33+ # 1-2-5-6-7 3-8-9-4
34+ uf .union (9 , 4 )
35+ print (uf .connected (4 , 9 )) # true
Original file line number Diff line number Diff line change 1+ class UnionFind :
2+ def __init__ (self , size ):
3+ self .root = [i for i in range (size )]
4+ # changing quickfind to have the parent node be stored in the array
5+ # effectively making it an O(1) operation to find the root of a given node
6+ # however, union will take a hit in performance
7+
8+ def find (self , n ):
9+ return self .root [n ]
10+
11+ def union (self , a , b ):
12+ fa = self .find (a )
13+ fb = self .find (b )
14+ if fa != fb :
15+ for i , v in enumerate (self .root ):
16+ if fa == v :
17+ self .root [i ] = fb
18+
19+ def connected (self , x , y ):
20+ return self .find (x ) == self .find (y )
21+
22+
23+ # Test Case
24+ uf = UnionFind (10 )
25+ # 1-2-5-6-7 3-8-9 4
26+ uf .union (1 , 2 )
27+ uf .union (2 , 5 )
28+ uf .union (5 , 6 )
29+ uf .union (6 , 7 )
30+ uf .union (3 , 8 )
31+ uf .union (8 , 9 )
32+ print (uf .connected (1 , 5 )) # true
33+ print (uf .connected (5 , 7 )) # true
34+ print (uf .connected (4 , 9 )) # false
35+ # 1-2-5-6-7 3-8-9-4
36+ uf .union (9 , 4 )
37+ print (uf .connected (4 , 9 )) # true
Original file line number Diff line number Diff line change 1+ # The vey basics of union find and disjoint sets
2+ # Basically an array and within that array lies a disjoint set
3+
4+
5+ # There are two functions when discussing disjoint sets
6+
7+ # find(a) which takes in a single argument and returns the root of
8+ # that particular node
9+
10+ # union(a,b) which takes in two arguments and combines them together
11+ # let's watch a quick video on how this works and then implement from there
12+
13+ # First lets implement UnionFind as an object and instantiate it with an array
14+
15+ class UnionFind :
16+ def __init__ (self , size ):
17+ self .root = [i for i in range (size )]
18+
19+ # union connects two nodes with a left bias meaning that b will always
20+ # connect to a
21+ def union (self ,a ,b ):
22+ # Basically we want to take the parent node of the given thing
23+ fa = self .find (a )
24+ fb = self .find (b )
25+ if fa != fb :
26+ self .root [fa ] = fb
27+
28+ # takes in a node a and returns the root node of such
29+ def find (self , a ):
30+ while a != self .root [a ]:
31+ a = self .root [a ]
32+ return a
33+
34+ uu = UnionFind (10 )
35+
36+ print (uu .root )
37+ uu .union (0 ,1 )
38+ uu .union (0 ,2 )
39+ uu .union (1 ,3 )
40+ uu .union (4 ,8 )
41+ uu .union (5 ,6 )
42+ uu .union (5 ,7 )
43+ print (uu .root )
44+ print ([i for i in range (10 )])
Original file line number Diff line number Diff line change 1+ # Optimized union find program that implements union by rank
2+
3+ class UnionFind :
4+ def __init__ (self , size ):
5+ self .root = [i for i in range (size )]
6+ self .rank = [1 ] * size
7+
8+ # Recurrsively update root
9+ def find (self , n ):
10+ if self .root [n ] != n :
11+ self .root [n ] = self .find (self .root [n ])
12+ return self .root [n ]
13+
14+ def union (self , a , b ):
15+ fa = self .find (a )
16+ fb = self .find (b )
17+
18+ if fa != fb :
19+ if self .rank [fa ] > self .rank [fb ]:
20+ self .root [fb ] = fa
21+ elif self .rank [fa ] < self .rank [fb ]:
22+ self .root [fa ] = fb
23+ else :
24+ self .root [fa ] = fb
25+ self .rank [fb ] += 1
26+
27+ def connected (self , x , y ):
28+ return self .find (x ) == self .find (y )
29+
30+ # Test Case
31+ uf = UnionFind (10 )
32+ # 1-2-5-6-7 3-8-9 4
33+ uf .union (1 , 2 )
34+ uf .union (2 , 5 )
35+ uf .union (5 , 6 )
36+ uf .union (6 , 7 )
37+ uf .union (3 , 8 )
38+ uf .union (8 , 9 )
39+ print (uf .connected (1 , 5 )) # true
40+ print (uf .connected (5 , 7 )) # true
41+ print (uf .connected (4 , 9 )) # false
42+ # 1-2-5-6-7 3-8-9-4
43+ uf .union (9 , 4 )
44+ print (uf .connected (4 , 9 )) # true
You can’t perform that action at this time.
0 commit comments