Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 55ece64

Browse files
committed
union find with path compression approach
1 parent df614e2 commit 55ece64

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
union_find_with_path_compression.py
3+
An implementation of union find with path compression data structure.
4+
Union Find Overview:
5+
------------------------
6+
A disjoint-set data structure, also called union-find data structure implements two functions:
7+
union(A, B) - merge A's set with B's set
8+
find(A) - finds what set A belongs to
9+
Union with path compression approach:
10+
Each node visited on the way to a root node may as well be attached directly to the root node.
11+
attach the smaller tree to the root of the larger tree
12+
Time Complexity : O(a(n)), where a(n) is the inverse of the function n=f(x)=A(x,x) and A is the extremely fast-growing Ackermann function.
13+
Psuedo Code: http://en.wikipedia.org/wiki/Disjoint-set_data_structure
14+
"""
15+
class UnionFindWithPathCompression:
16+
def __init__(self, N):
17+
if type(N) != int:
18+
raise TypeError, "size must be integer"
19+
if N < 0:
20+
raise ValueError, "N cannot be a negative integer"
21+
self.parent = []
22+
self.rank = []
23+
self.N = N
24+
for i in range(0, N):
25+
self.parent.append(i)
26+
self.rank.append(0)
27+
28+
def make_set(self, x):
29+
if type(x) != int:
30+
raise TypeError, "x must be integer"
31+
if x != self.N:
32+
raise ValueError, "a new element must have index {0} since the total num of elements is {0}".format(self.N)
33+
self.parent.append(x)
34+
self.rank.append(0)
35+
self.N = self.N + 1
36+
37+
def union(self, x, y):
38+
self.__validate_ele(x)
39+
self.__validate_ele(y)
40+
x_root = self.find(x)
41+
y_root = self.find(y)
42+
if x_root == y_root:
43+
return
44+
# x and y are not already in same set. Merge them
45+
if self.rank[x_root] < self.rank[y_root]:
46+
self.parent[x_root] = y_root
47+
elif self.rank[x_root] > self.rank[y_root]:
48+
self.parent[y_root] = x_root
49+
else:
50+
self.parent[y_root] = x_root
51+
self.rank[x_root] = self.rank[x_root] + 1
52+
53+
def __find(self, x):
54+
if self.parent[x] != x:
55+
self.parent[x] = self.__find(self.parent[x])
56+
return self.parent[x]
57+
58+
def find(self, x):
59+
self.__validate_ele(x)
60+
if self.parent[x] == x:
61+
return x
62+
else:
63+
return self.find(self.parent[x])
64+
65+
def is_connected(self, x, y):
66+
self.__validate_ele(x)
67+
self.__validate_ele(y)
68+
return self.find(x) == self.find(y)
69+
70+
def __validate_ele(self, x):
71+
if type(x) != int:
72+
raise TypeError, "{0} is not an integer".format(x)
73+
if x < 0 or x >= self.N:
74+
raise ValueError, "{0} is not in [0,{1})".format(x, self.N)
75+

0 commit comments

Comments
 (0)