Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added Union Find progression basic, path_compression, quickfind, quic… #212

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Graphs/UnionFind/01_basic_disjointset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# The vey basics of union find and disjoint sets
# Basically an array and within that array lies a disjoint set


# There are two functions when discussing disjoint sets

# find(a) which takes in a single argument and returns the root of
# that particular node

# union(a,b) which takes in two arguments and combines them together
# let's watch a quick video on how this works and then implement from there

# First lets implement UnionFind as an object and instantiate it with an array

class UnionFind:
def __init__(self, size):
self.root = [i for i in range(size)]

# union connects two nodes with a left bias meaning that b will always
# connect to a
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
for i in range(len(self.root)):
if self.root[i] == rootY:
self.root[i] = rootX

# takes in a node a and returns the root node of such
def find(self, a):
while a != self.root[a]:
a = self.root[a]
return a

uu = UnionFind(6)

print(uu.root)
uu.union(0,1)
uu.union(4,5)
uu.union(1,4)

print(uu.root)
#print([i for i in range(6)])
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions Graphs/UnionFind/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Overview:
A way that we can easily check membership in an undirected graph is through the use of UnionFind aka. Disjoint Set.
The word Union Find and Disjoint Set are relatively interchangable within the coding world with Disjoint Set reffering to
the data structure and Union Find referring to the actual algorithm. This data structure plays an especially important role in Kruskal's algorithm for finding a minimum spanning tree as it can
help determine if an undirected graph contains any cycles.

## What is a Disjoint Set (Union Find)?
A Disjoint set is essentially an undirected graph. It's a datastructure that stores a collection of disjoint (non-overlapping) sets.
It stores a subsection of a set into disjoint subsets.
The basic operations are as follows:

### Find()
Find the root of a given disjoint subset

```python
def find(self, a):
while a != self.root[a]:
a = self.root[a]
return a
```

### Union()
Combine subsets into a larger subset
```python
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
for i in range(len(self.root)):
if self.root[i] == rootY:
self.root[i] = rootX
```

At the initialization of a disjoint set each element represents a separate subset with its parent being the element itself.

This is what's called the root array.


## Algorithm of UnionFind in Python
Every time we reach a new node, we will take the following steps:
1. Call find(x), and find(y) to find the root of each of the subsets, with x and y representing the elements to combine.
2. Loop through entire root array and update the root of y with the root of x

## Time & Space Complexity
* **Time Complexity:**
Time complexity of the basic UnionFind algorithm is `O(N)`, for find and `O(N)` for union, where N is the number of elements

However, depending on the uitilization of this algorithm it often can scale to `O(N^2)` as you often times find yourself doing
N operations of Union.


* **Space Complexity:**
Since the initialization array is of length N.

The space complexity of the UnionFind algorithm is `O(N)`, where N is the number of elements

## Input & Output:

At the start each element is the root of itself.
```python
uf = UnionFind(6)
```
<img width=50% src="../UnionFind/Images/basic_union/basic_union.png">

```python
uf.union(0,1)
```
When we call the union function we update the root of one element to the root of the other.

<img width=50% src="../UnionFind/Images/basic_union/basic_union_1.png">

```python
uf.union(4,5)
```


<img width=50% src="../UnionFind/Images/basic_union/basic_union_2.png">

```python
uf.union(1,4)
```

This also applies to all subsequent elements with the same root

<img width=50% src="../UnionFind/Images/basic_union/basic_union_3.png">