# Data Structures

<details>

<summary>Course Content</summary>

A tentative list of topics that will be covered in this course are:

Introduction to Algorithms, Insertion Sort, Divide and Conquer, Merge Sort, Solving Recurrences, Hashing, Binary Search Tree, Red Black Tree, Augmenting Data Structures, Disjoint Sets, Graphs, Dijkstra's Algorithm, Maximum Flow, Matching, String Matching, KMP Alogrithm, Dynamic Programming (Rod Cutting, LCS, etc. ), Complexity classes P, NP, co-NP, NP-complete, NP-Hard, Example reductions between problems.

</details>

<details>

<summary>Exams</summary>

* 55% internal
  * 30% for 2 assignment&#x20;
    * [1st Deadline ⇒ 23Feb](https://m-tech-in-artificial-intelligenc.gitbook.io/manvendrapratapsinghdev/trimester-1/broken-reference)
  * **25% Quiz**&#x20;
    * 23 feb ⇒ 1st Quiz
* 45% Main

</details>

<details>

<summary>Material </summary>

* [**Class Recordings**](https://general-smile-94b.notion.site/DSA-Class-Recording-1980dfee4e4380ed9bb0c9a2b4787540)
* [**Class Material**](https://github.com/manvendrapratapsinghdev/IITJMaterial/tree/main/T1/DSA)
* [**Books**](https://m-tech-in-artificial-intelligenc.gitbook.io/manvendrapratapsinghdev/trimester-1/broken-reference)

</details>

## Lecture 1: *(<mark style="color:orange;">11/01/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1pgt51KGnl74hSujvVaHRswwKOwF_nCro/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FhNQL67ODxwbXbeFCB8xw%2FLecture%201_class_notes.pdf?alt=media&token=b72a0b71-a87a-4aec-8baf-45e982c6fdf1>" %}

What is Algo

Problem&#x20;

When we say algo is solving

## Lecture 2:*(<mark style="color:orange;">12/01/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1TGfVwGxfmn1Jz3mWV-nqs7y-4tvVfFeL/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FwN3meNsfsg7YdGGiiFGT%2FLecture%202_class_notes.pdf?alt=media&token=25b09f0f-f91c-4952-9b7c-c60ea365307d>" %}

### InsertionSort:

**Technic** ==> Incremental

{% code title="Pseudocode code" %}

```csharp
(A, n)
    for i = 2 to n:
        key = arr[i]
        j = i - 1
        while j > 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j = j - 1
        arr[j + 1] = key

```

{% endcode %}

```python
// Python Code of Insertion sort
array = [6, 5, 4, 3, 1, 2]
print("Initial Array =", array)
for i in range(1,len(array)):
  ele = array[i]
  j = i-1
  while j>=0 and ele< array[j]:
    array[j+1] = array[j]
    j = j-1
  array[j+1] = ele
  print("i =", i, "Then Array =", array)
```

```python
// Dry Run
Initial Array = [6, 5, 4, 3, 1, 2]
i = 1 Then Array = [5, 6, 4, 3, 1, 2]
i = 2 Then Array = [4, 5, 6, 3, 1, 2]
i = 3 Then Array = [3, 4, 5, 6, 1, 2]
i = 4 Then Array = [1, 3, 4, 5, 6, 2]
i = 5 Then Array = [1, 2, 3, 4, 5, 6]
```

### Measure the Run Time

**Code it and check the runtime**

**Drawback**:&#x20;

* Depend upon the size of Array
* Hardware depends&#x20;

### Run Time&#x20;

No of basic operation an algo perform as function of input size f(n)

let's take the example of InsertionSort

| <p><br></p>                    | Basic operation | No of times         | Total Time |
| ------------------------------ | --------------- | ------------------- | ---------- |
| for i = 2 to n:                | 2               | N                   | 2n         |
| key = arr\[i]                  | 1               | N-1                 | N-1        |
| j = i - 1                      | 1               | N-1                 | N-1        |
| while j > 0 and arr\[j] > key: | 2               | Σti    i = 2..n     | 2 \*Σti    |
| arr\[j + 1] = arr\[j]          | 1               | Σt(i-1)    i = 2..n | Σt(i-1)    |
| j = j - 1                      | 1               | Σt(i-1)    i = 2..n | Σt(i-1)    |
| arr\[j + 1] = key              | 1               | N-1                 | N-1        |

```
T(n)  =   Basic operation  * No of times
T(n)  =  2n + 3(n-1) + 2 Σ times + 2 Σ (ti-1)

```

**Best case scenario:** &#x20;

```
when ti = 1
= 2n + 3(n-1) + 2(n-1) + 0 
  = 7n - 5 ==> an + b where a and b are const
= O(n)
```

**Worst case scenario**&#x20;

```
when ti = i
= 2n + 3(n-1) + 2(n(n+1)/2-1) 2(n-1)/2-1
= a*n2 + B, an2 + b where a and b are const
= O(n2)
```

#### &#x20;Why only leading term matters

> *Larger power take more time to execute for large number of data set it might take less time for smaller vales depending on the expression.* **We can prove this by graph**

## Lecture 3:*(<mark style="color:orange;">18/01/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1aoe4ySwsR52dkSfV2ZAQvWYCvIbBqLIb/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FYvDSlyjTJa77fWijCLQM%2FLecture%203_class_notes.pdf?alt=media&token=f74021cd-7cce-4f69-a2b9-f9313e51e05c>" %}

### Merge Sort

**Technic** => Divide and conquer&#x20;

**Divide** => one or more smaller problem

**conquer** => Solve the sub problem using recursively&#x20;

**Combine** => Merge the solution of small problem and create solution of problem&#x20;

<pre class="language-clike" data-title="Pseudocode code " data-overflow="wrap"><code class="lang-clike">call => MergeSort(arr, 1, length(arr))
MergeSort(arr, s, e):
    if s >= e:
        return
    mid = s + (e - s)/2
    MergeSort(arr, s, mid)   
    MergeSort(arr, mid+1, e)
    Merge(arr, arr[s: mid], arr[mid+1: e])   
// end of method MergeSort
<strong>Merge(arr, left, right):
</strong>    i = 1, j = 1, k = 1
    n = length(left)
    m = length(right)
    while i &#x3C;=n and j &#x3C;=m:
        if  left[i]&#x3C;= right[j]:
            arr[k]= left[i]
            i++
         else    
             arr[k]= right[j]
             j++
         k++
         //end of while
    while i &#x3C;=n:
            arr[k]= left[i]
            i++, k++     
    while j &#x3C;=m:
            arr[k]= right[j]
            j++, k++
    //end of Merge method      
</code></pre>

### Complexity&#x20;

$$
T(n)=2^kT(n/2 ^k)+cn
$$

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2Fshix7ZHWOndME0gVCJlh%2FScreenshot%202025-01-20%20at%208.34.14%E2%80%AFPM.png?alt=media&#x26;token=97a1e08f-a28c-4007-b307-785c70791ae3" alt="" width="375"><figcaption><p>T(n) = c’NlogN +cN => O(NlogN) (b/c it is leading term)</p></figcaption></figure>

### Recurrence Reaction

A is a equation a/c to which a term of sequence of no is equal to some combination of previous term

Recursive Tree Method

$$
T(n) =  3\*T(n/4) +cn^2
$$

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FJbZAzLKkntwUeL6cxcDG%2FScreenshot%202025-01-19%20at%209.55.52%20AM.png?alt=media&#x26;token=6f038c8f-7788-4451-ab1e-a742bf3adfcb" alt="" width="375"><figcaption><p>level => LogN +1</p></figcaption></figure>

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FFqH2bcRrmJU7N9BeOx78%2FScreenshot%202025-01-20%20at%208.37.26%E2%80%AFPM.png?alt=media&#x26;token=26005bd2-3092-4e51-b377-5f23725710db" alt="" width="375"><figcaption></figcaption></figure>

**Height** => log4(n+1)

**Length**  => (Log4(n+1))3

**Total Time** =>  O(n2)

## Lecture 4:*(<mark style="color:orange;">19/01/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1RvZ1KQZWuhIsJO4WfjdbTtMGPUq22wmh/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FdU0bS9dGSaXORVHRh4lg%2FLecture%204_class_notes.pdf?alt=media&token=d7aca7dd-09d0-43f7-a170-eac1ed55b63b>" %}

**Self learning:** Stack, queue and Linked-list

### Hashing

It is typically to maintain a **dynamic set** that support **three operations** => CRD

**Dynamic set**: Set of elements where every element has key

### Direct-address Tables (Array)

`Every election of Dynamic set has a distinct key`&#x20;

`Every element has a key. Like in array index is key`

Key = {0,1,… n-1}

**Cons** => Space issue

To tackle this problem we use Hash Tables

### Hash Tables

In hash table denoted by T\[0: m-1], whr m< n

Key = {0,1,… n-1}

#### Hash function

$$
T\[h(x.key)],  where  h: U {0,1…m-1}
$$

**Issue** when two values map on same key this is called **Collision.**

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FiQpPbSinEaHp5egEElPw%2FScreenshot%202025-01-20%20at%2010.35.42%E2%80%AFPM.png?alt=media&#x26;token=07547c0f-e5b3-4f32-a58c-3680fca1ef41" alt="" width="375"><figcaption><p>2 is <strong>Collision point</strong></p></figcaption></figure>

#### Chaining&#x20;

* to handele collision
* we create a linked list&#x20;
* we will map the key to a linked list and that connect the new element

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FLykCX7ascKA4MrZlV9NV%2F_-%20visual%20selection.png?alt=media&#x26;token=a116aa4f-91a9-46c2-8587-be0ff8f3f319" alt="" width="563"><figcaption></figcaption></figure>

## Lecture 5: *(<mark style="color:orange;">25/01/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1X6MibH2gHpPqvyX6O505QkVrA4RvXlB8/view?usp=sharing):

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FH0Pg5c1sDJzwrMZsXJJi%2FLecture%205.pdf?alt=media&token=b278e65a-3895-40a2-8252-92638aed713b>" %}

#### **Independent Uniform Hashing**

* **Definition**: A hash function $$h: U \rightarrow {0, 1, \ldots, m-1}$$ maps keys from a universe $$U = {0, 1, \ldots, n-1}$$ to a hash table $$T\[0: m-1]$$ ($$m < n$$) such that:
  * Each key $$k$$ is assigned a uniformly random slot $$h(k)$$.
  * Repeated calls for the same $$k$$ return the same $$h(k)$$.
* **Expected Chain Length**:
  * For slot $$j$$, define random variables $$X\_0, X\_1, \ldots, X\_{n-1}$$, where $$X\_i = 1$$ if $$h(i) = j$$, else $$0$$.
  * The chain length $$T\_j = X\_0 + X\_1 + \ldots + X\_{n-1}$$.
  * Using linearity of expectation:

    $$
    \mathbb{E}\[T\_j] = \sum\_{i=0}^{n-1} \mathbb{E}\[X\_i] = n \cdot \frac{1}{m} = \frac{n}{m}
    $$
  * When $$n = m$$, search time is $$O(1)$$.

***

#### **Open Addressing**

* **Concept**: All elements are stored directly in the hash table. Collisions are resolved by probing subsequent slots.
* **Probe Sequence**: A permutation of $$\langle h(k, 0), h(k, 1), \ldots, h(k, m-1) \rangle$$ for key $$k$$.
* **Operations**:
  * **Insert**: Iterate through probe sequence until an empty slot is found.

    ```plaintext
    OA-INSERT(T, x):
      i = 0
      do:
          q = h(x.key, i)
          if T[q] == NIL:
              T[q] = x
              return q
          else:
              i += 1
      while i ≠ m
      error "Hash table overflow"
    ```
  * **Search**: Follow probe sequence until the key is found or a NIL slot is encountered.
  * **Delete**: Marking a slot as NIL can break probe sequences for other keys, requiring careful handling.
* **Probing Methods**:
  * **Linear Probing**: $$h(k, i) = (h'(k) + i) \mod m$$.
  * **Double Hashing**: $$h(k, i) = (h\_1(k) + i \cdot h\_2(k)) \mod m$$, where $$\gcd(h\_2(k), m) = 1$$.

***

#### **Binary Search Trees (BSTs)**

* **Structure**: A binary tree where each node contains:
  * Key and satellite data.
  * Pointers to parent, left child, and right child.
* **BST Property**: For any node $$x$$:
  * Nodes in the left subtree have keys $$\leq x$$.key.
  * Nodes in the right subtree have keys $$\geq x$$.key.
* **Supported Operations**:
  * Insert, Search, Delete.
  * Find minimum/maximum.
  * Find successor/predecessor.

***

#### **Summary**

* **Hashing**: Independent uniform hashing ensures an expected chain length of $$\frac{n}{m}$$. Open addressing resolves collisions via probing but requires careful deletion handling.
* **BSTs**: Maintain dynamic sets with efficient operations by preserving the BST property. Probing methods like linear and double hashing enable collision resolution in open addressing.

## Lecture 6: *(<mark style="color:orange;">02/02/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1dMTmKL823nMtTo-vWRZOF0AJfHjrISYm/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2Fzc8cteYUWWLunhe0oE6s%2FLecture%206.pdf?alt=media&token=883d2afd-e2ab-4be3-9f3d-c446a7c50961>" %}

### <mark style="color:purple;">**Binary Search Tree**</mark>

{% embed url="<https://manvendrapratapsinghdev.medium.com/bst-as-simple-as-a-cup-of-tea-fd5946b327e1>" %}
Read this
{% endembed %}

## Lecture 7: *(<mark style="color:orange;">08/02/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1SeU_q0Y0rR-lV-6o09XqNRPFZoTclz0N/view?usp=sharing):

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FhOrGXgwcZub1y7UcH366%2FLecture%207.pdf?alt=media&token=2de14314-789e-4a4b-90ea-c6efeb8f2486>" %}

### <mark style="color:purple;">**Red-Black Trees**</mark>

All you need to about R-B is added in this blog:&#x20;

{% embed url="<https://manvendrapratapsinghdev.medium.com/red-black-tree-deletion-step-by-step-guide-dc01662985f7>" %}

Self-balancing BSTs that maintain O(log n) height through these properties:

1. Every node is **red** or **black**
2. Root is always black
3. All Nil leaves are black
4. Red nodes cannot have red children
5. Equal black nodes count (black height) on all root-to-leaf paths\[1]

## Lecture 8: *(<mark style="color:orange;">09/02/2025</mark>`)`*

[**Class Recording**](https://drive.google.com/file/d/1guUqlHYvbBBmtn5PKgxYkq8kznAC9qcb/view?usp=sharing):

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FTwPL6yrx5cx4IC4Oc6Xr%2FLecture%208.pdf?alt=media&token=a2021a7e-643e-4c8a-9caa-204c7c59626c>" %}

Red-Black Trees are balanced binary search trees that maintain logarithmic height through color-based constraints. This lecture covers their height properties and insertion mechanics through detailed proofs and case analyses.

## Lecture 9: *(<mark style="color:orange;">15/02/2025</mark>`)`*

<mark style="color:red;">**Class canceled**</mark>

## Lecture 9: *(<mark style="color:orange;">16/02/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1mCfSKVs9e7Bi1MZegioY71u2-WBvS-SK/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FMLoUlSf3eoq3VNat2Hhl%2FLecture%209.pdf?alt=media&token=84a902c3-09b4-4a70-8e23-c9e4455746b0>" %}

### <mark style="color:purple;">**Red-Black Tree Deletion**</mark>

All you need to about R-B deletion is added in this blog:&#x20;

{% embed url="<https://manvendrapratapsinghdev.medium.com/red-black-tree-deletion-step-by-step-guide-dc01662985f7>" %}

## Lecture 10: *(<mark style="color:orange;">22/02/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1rAY886NHZiD4GcE6vkEeVUrpBXZFZzXo/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FPCtPg04NGyZCTNoZx4sI%2FLecture%2010.pdf?alt=media&token=17e338c4-84f6-4a93-8d30-2e25fca48720>" %}

* Red-Black Tree Deletion Cases

## Lecture 11: *(<mark style="color:orange;">23/02/2025</mark>`)`*

<mark style="color:red;">**Minor Exam**</mark>

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FMBkajSrXMexg07Z9SIkk%2FMinor.pdf?alt=media&token=cd02d7e9-e385-4c53-b3c5-99483cffdeb3>" %}

## Lecture 11: *(<mark style="color:orange;">01/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1d2CLGRxjBvSgVDwPRqqKh2MQ0bw34oK2/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FsJojDhxJk9rH8E4rqvPv%2FLecture%2011.pdf?alt=media&token=5b44b08f-8a36-4e7f-8411-b9699ad4aa8c>" %}

### <mark style="color:purple;">Augmenting Data Structure</mark>

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FKQ8rRixgI5xDuxlyNXQh%2FAugmenting%20Data%20Structures%2C.pdf?alt=media&token=935d5cf9-979d-4c3b-bbb1-eda255fd61ed>" %}

It will be the extension of RB tree with extra value number of element it contain in it’s sub tree.

#### <mark style="color:blue;">Finding the ith element</mark>

```python
FUNCTION Ith_element(node, i):
1.  IF node == NULL:
2.      RETURN NULL  // i is out of range

3.  Left_node_size = 0
4.  IF node.left ≠ NULL:
5.      Left_node_size = node.left.size

6.  IF i == Left_node_size + 1:
7.      RETURN node.key  // Found the i-th element

8.  ELSE IF i ≤ Left_node_size:
9.      RETURN Ith_element(node.left, i)  // Traverse in left subtree

10. ELSE:
11.     RETURN Ith_element(node.right, i - (Left_node_size + 1))  // Traverse in right subtree

```

#### <mark style="color:blue;">Finding the Rank of element</mark>

```python
FUNCTION rank(T, key):
1.  x = find_node(T.root, key)  // Find the node containing 'key'
2.  IF x == NULL:
3.      RETURN 0  // Key not found

4.  r = x.left.size + 1
5.  y = x
6.  while y ≠ T.root:
7.      if y == y.p.right:
8.          r = r + y.p.left.size + 1
9.      y = y.p
10. return r

FUNCTION find_node(node, key):
11. WHILE node ≠ NULL AND node.key ≠ key:
12.     IF key < node.key:
13.         node = node.left
14.     ELSE:
15.         node = node.right
16. RETURN node

```

## Lecture 12: *(<mark style="color:orange;">02/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1mbbbS1GSUVPWirv09FuTgzvwfl9yCFS9/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FR3GwVacTxR6Kz4CW8oSa%2FLecture%2012.pdf?alt=media&token=d5451d60-593c-4b36-9f50-06876a5fd9b8>" %}

## &#x20;<mark style="color:purple;">Data Structure</mark>

* Disjoint-set is an advanced data structure used for handling collections of disjoint dynamic sets.
* Also known as **Union-Find** or **Merge-Find Set**.
* Commonly used in **graph algorithms** to determine connected components.

<details>

<summary>Sets</summary>

* A **set** is a collection of distinct objects.
* **nion**: Combines two sets into one.
* **Intersection**: Finds common elements between two sets.
* **Disjoint Sets**: Two sets are **disjoint** if they have no common elements.

</details>

####

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FyoswerEhWRhg7rr5f1Hz%2FDisjoint%20Set.pdf?alt=media&token=24f421be-b9a9-4bac-8949-0cd070ff2574>" %}

#### <mark style="color:blue;">**Core Operations**</mark>

The disjoint-set data structure supports three fundamental operations:

**1. MAKE-SET(x)** Creates a new set containing only element `x`.

```
MAKE-SET(1), MAKE-SET(2)
Sets: {1}, {2}
```

**2. UNION(x, y)** Merges the sets containing `x` and `y` into one.

```
UNION(2, 6) → {2, 6}
```

**3. FIND-SET(x)** Finds the representative (leader) of the set containing `x`.

```
EditFIND-SET(2) → 1 (if 1 is the representative)
```

#### <mark style="color:blue;">Implementation</mark>

The most efficient implementation uses a forest of trees:

* Each element is a node in a tree
* Each tree represents one subset
* The root of each tree serves as the representative of that set
* Initially, each element forms its own set (is its own parent)

#### <mark style="color:blue;">**Optimizations (Heuristics)**</mark>

#### **1. Union by Rank**

* Always attach the tree with fewer nodes to the root of the larger tree.
* Ensures shallower trees, improving efficiency.

#### **2. Path Compression**

* During `FIND-SET(x)`, update each node on the path to directly point to the root.
* Makes future queries much faster

### **Applications**

* **Graph Algorithms**:
  * Handling queries about connectivity in graphs that change over time.
  * **Kruskal's Algorithm** for Minimum Spanning Tree.
* **Networking**: Finding clusters in a network.
* **Image Processing**: Segmenting images into different regions based on pixel similarity

checkout this [*blog* ](https://www.hackerearth.com/practice/data-structures/disjoint-data-strutures/basics-of-disjoint-data-structures/tutorial/)for more information about Disjoint

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FiJUIcKDAWsqSYuxSSIJ9%2F1.jpg?alt=media&#x26;token=4ca0f220-2f26-4f32-b9ec-86fc4468be77" alt=""><figcaption></figcaption></figure>

## Lecture 13: *(<mark style="color:orange;">08/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/11TynGRonsxZu2p1xyccmW0vi7-PeXwA-/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FeKhHUmENFWc5WLOXny3E%2FLecture%2013.pdf?alt=media&token=a61a71b5-3740-42b8-a912-4d4fb317f4fb>" %}

## <mark style="color:purple;">Disjoint As Tree</mark>

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2Ft5X0o39ZaKl4W9gldJhC%2F0.jpg?alt=media&#x26;token=c4a7eaf2-7623-4a6d-922a-3076dd5e8621" alt=""><figcaption></figcaption></figure>

#### MAKE-SET

```
function MakeSet(x) is
    if x is not already in the forest then
        x.parent := x
        x.size := 1    // if nodes store size
        x.rank := 0    // if nodes store rank
    end if
end function

```

Complexity of Make-Set is ***O(1)***

#### FIND-SET

```
function FIND-SET(x) is
    if x.parent == x then
     return x
    else 
     return FIND-SET(x.parent)
    end if
end function

```

Complexity of Find-Set is ***O(log n)***

#### UNION

```
function UNION(x, y) is
    x_root := FIND-SET(x)
    y_root := FIND-SET(y)
    if x_root == y_root then
        return
    end if
    if x_root.rank < y_root.rank then
        x_root.parent := y_root
    else if x_root.rank > y_root.rank then
        y_root.parent := x_root
    else
        // If ranks are the same, make one point to the other and increment its rank
        y_root.parent := x_root
        x_root.rank := x_root.rank + 1
    end if
end function

```

while making node we perform Union and In Union we perform **rank check operation** not just adding in parallel

By this we can say, In every tree the max height is **O(logn)** so \
Find node complexity = O(logn) \
\
Complexity of Make-Set is 2\*O(log n) ***⇒ O(log n)***&#x20;

<mark style="color:green;">**Example of Disjoint-Tree**</mark>

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FCpchrITwdw3rcBRERPgQ%2F1.png?alt=media&#x26;token=60a414cf-5e59-4c66-b9e8-a739a244c0da" alt=""><figcaption></figcaption></figure>

### <mark style="color:purple;">Path compression Heuristic</mark>

Path compression is an optimization in the **Find** operation that flattens the tree structure by making nodes point directly to the root.

#### **Why We Do It?**

* To **speed up future Find operations** by reducing tree depth.
* Helps in **keeping the tree nearly flat**, making Union-Find operations almost constant time **O(α(n))**, where **α(n)** is the inverse Ackermann function (very slow-growing).

#### **Benefit**

* **Improves efficiency**, making `Find(x)` nearly **O(1)** for large datasets.
* Reduces redundant traversal, **optimizing memory and computation** in Disjoint Set operations. 🚀

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FRixPIbdkfNIpOFAcSF0C%2FScreenshot%202025-03-08%20at%2011.29.47%20AM.png?alt=media&#x26;token=a108ffc3-9f79-4e77-8681-1655e70e079f" alt=""><figcaption></figcaption></figure>

{% embed url="<http://visualgo.net/en/ufds>" %}

## Lecture 14: *(<mark style="color:orange;">09/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1PLWuweJK6386fvmHuv2K2GohgiZmr1K9/view?usp=sharing)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FpglBkKpe1bZUL2DCZTiL%2FLecture%2014.pdf?alt=media&token=96a5e44b-4ef5-47c5-91d5-fc62aeabf99a>" %}

### <mark style="color:purple;">Graph</mark>&#x20;

1. **Graphs in Real Life**\
   Graphs are used to represent relationships in real-world scenarios, such as airline networks, job assignments, and network connectivity.
2. **Undirected and Directed Graphs**\
   An undirected graph consists of vertices connected by edges with no direction, whereas a directed graph has edges with specified directions.
3. **Graph Representation**\
   Graphs can be represented using adjacency lists (efficient for sparse graphs) or adjacency matrices (efficient for checking edge existence).
4. **Basic Terminology**\
   Concepts like adjacency, degree of a vertex, paths, cycles, and shortest distance help describe relationships between nodes in a graph.
5. **Graph Applications**\
   Graph theory is applied in solving shortest path problems, network flow optimization, social network analysis, and circuit design.

## Lecture 15: *(<mark style="color:orange;">15/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1klziVZ0R6uGin9uMrA3D8R3DBWO6UWE5/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2F4O9MgZjqz3a3LbmOq8Zn%2FLecture%2015.pdf?alt=media&token=c82de860-fd41-4e00-88ad-39d6ee0577c2>" %}

### <mark style="color:purple;">Breadth-first Search, Dijkstra</mark>

## Lecture 16: *(<mark style="color:orange;">22/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/12JfJbMdYa8KNJRZMRVwUIUbHkx5NwWRu/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FFLIDnurTz8F013zXCXEI%2FLecture%2016.pdf?alt=media&token=198921c0-af40-4a35-ad04-9971dad603e8>" %}

### <mark style="color:purple;">Dijkstra, Flow Networks</mark>

## Lecture 17: *(<mark style="color:orange;">23/03/2025</mark>`)`*

[**Class Recording**:](http://drive.google.com/file/d/1QEBXIvkwE7vmrjlYy4nyGhNe6UVQUwEe/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FYKwRnlUFjROZ9bfriTiU%2FLecture%2017.pdf?alt=media&token=5f714948-ab69-4f3b-a193-69f9501f197a>" %}

### <mark style="color:purple;">Flow Networks, Ford-Fulkerson Method</mark>

## Lecture 18: *(<mark style="color:orange;">29/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1VC-IJVf4Kcg4yBl_sRZjnNtBKp6e64kv/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FqjnBoQbL37uhY0uPaXx2%2FLecture%2018.pdf?alt=media&token=5f326e16-c78b-4ee2-8c43-702355d95413>" %}

### <mark style="color:purple;">Bipartite Maximum Matching</mark>

<mark style="color:purple;">Bipartite Graph</mark>&#x20;

<mark style="color:purple;">Bipartite matching</mark>

<mark style="color:purple;">Maximum Bipartite matching</mark>

#### **Bipartite Matching**

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FhZ7wobNLfVtSHwXqH8Py%2FBipartite%20Matching.pdf?alt=media&token=f4b350f2-3737-43f7-91c3-e8ea392b86ac>" %}

## Lecture 19: *(<mark style="color:orange;">30/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1ojSnfHymR50_wnqmKbLnniw03hT2XL2-/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2Fw073G8k2JlK4O7j4Aguc%2FLecture%2019.pdf?alt=media&token=82e09142-edd4-44f2-ab99-961e06496c4e>" %}

### <mark style="color:purple;">Dynamic Programming</mark>

Dynamic Programming (DP) is a powerful algorithmic technique to solve complex problems by breaking them down into simpler subproblems. It is particularly effective for **optimization** problems that exhibit two key properties: **overlapping** subproblems and **optimal** substructure

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FqoDdRfalMW2d9LwjQRNC%2Fdynamic-programming.jpeg?alt=media&#x26;token=5a615141-249e-47db-bd65-b839f6ff72b9" alt=""><figcaption></figcaption></figure>

### <mark style="color:blue;">**Road cutting problem**</mark>

​The Rod Cutting Problem is a classic optimization challenge where the objective is to determine the optimal way to cut a rod of length *n* into smaller segments to maximize total revenue, given a price table for each segment length<br>

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2F7lOkMTfpjqtTlVyjvvH5%2Froad.jpg?alt=media&#x26;token=6a0bcdb5-364e-403e-bf37-85966ebebea1" alt="" width="563"><figcaption></figcaption></figure>

## Lecture 20: *(<mark style="color:orange;">06/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/1Xqa-8fAp3BHoIlAsdcaFl_JyiVPO5Vm3/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FLdkC4HFHT8lq3lEzgv77%2FLecture%2020.pdf?alt=media&token=fa90efc0-5ae6-4dbf-8ebd-21db03a56342>" %}

### <mark style="color:purple;">More Dynamic Programming Examples</mark>

<mark style="color:blue;">**LCS Dynamic Programming**</mark>

* **Subsequence Definition**: Dropping 0+ characters while preserving order.
* **LCS Problem**: Find longest subsequence common to two strings.
* **Applications**: Measures similarity (e.g., DNA, text comparison).
* **Brute Force Approach**: Exponential time, checks all subsequences.
* **Optimal Substructure**: LCS can be built from solutions of subproblems.
* **Recurrence Relation**: Forms the DP backbone with match/mismatch rules.
* **Overlapping Subproblems**: Justifies using memoization/tabulation.
* **Top-Down DP**: Recursive + memoization avoids recomputation.
* **Bottom-Up DP**: Iteratively fills DP table using recurrence.
* **Top-Down vs Bottom-Up**: Trade-off between recursion and full coverage.
* **Time Complexity**: Both DP methods run in O(nm).

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2FiVFS52PRKubkYOMeidkS%2FNotebookLM%20Mind%20Map%20(1).png?alt=media&#x26;token=af1e3ad4-73f8-483d-aea0-cc43aab10ea5" alt=""><figcaption></figcaption></figure>

**Test you answer here:**

{% embed url="<https://www.cs.usfca.edu/~galles/visualization/DPLCS.html>" %}

## Lecture 21: *(<mark style="color:orange;">06/03/2025</mark>`)`*

[**Class Recording**:](https://drive.google.com/file/d/12q3l-1vqE_B5pXGBV7IalPwbMSroTbUs/view)

{% file src="<https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2Foekln9vWAvPTp5YH2USb%2FLecture%2021.pdf?alt=media&token=2ea0c810-333a-4776-b385-18517d1691de>" %}

### <mark style="color:purple;">P, NP, and NP-completeness</mark>

### <mark style="color:blue;">Search Vs Decision Problem</mark>

In computational complexity theory, search and decision problems represent two fundamental types of computational challenges.\
A decision problem asks a yes-or-no question based on given input values. For example:\
• Is a given number prime?\
• Does x evenly divide y?\
• Is a formula satisfiable?\
A search problem requires finding an actual solution rather than just determining its existence. For example:\
• Find a satisfying assignment for a formula\
• Find a clique of size k in a graph\
• Find a prime factor of a number

While both decision and search problems are fundamental in computational complexity theory, decision problems do hold several important advantages over search problems

Decision problems are often more tractable computationally. They typically require less computational resources since they only need to determine existence rather than construct a complete solution.

<mark style="color:orange;">**If a decision problem is not solvable in polynomial time, then its corresponding search problem cannot be solved in polynomial time either.**</mark>

### <mark style="color:blue;">Complexity Class P</mark>

<figure><img src="https://993787502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxTZGvcOxnCaOvsmUzDj5%2Fuploads%2F4bc1XCKsEEUWkgMoGtCT%2FP_Np.png?alt=media&#x26;token=89e03fd9-9959-45d8-9859-11c84284f746" alt=""><figcaption></figcaption></figure>

T**opics** of this lecture

1. **Search vs. Decision Problems**\
   Search problems find solutions; decision problems answer Yes/No.
2. **Complexity Class P**\
   P contains problems solvable in polynomial time.
3. **Complexity Class NP**\
   NP contains problems verifiable in polynomial time.
4. **P vs NP**\
   The key question: Is every NP problem also in P?
5. **NP-Completeness**\
   NP-complete problems are the hardest in NP; solving one solves all.
6. **SAT and 3SAT**\
   SAT and 3SAT are classic NP-complete problems involving Boolean formulas.
7. **NP-Complete Network**\
   Various NP-complete problems are interlinked by polynomial-time reductions.
