DSA_Complete_Study_Guide
DSA_Complete_Study_Guide
ALGORITHMS
Complete Study Guide
Units 1 – 5 | With Examples & Diagrams
Algorithm
for i = 0 to n-2:
for j = 0 to n-2-i:
if arr[j] > arr[j+1]:
swap(arr[j], arr[j+1])
Example
Array: [64, 34, 25, 12, 22]
Pass Array After Pass Swaps
Pass 1 [34, 25, 12, 22, 64] 4
Pass 2 [25, 12, 22, 34, 64] 3
Pass 3 [12, 22, 25, 34, 64] 2
Pass 4 [12, 22, 25, 34, 64] 0 → DONE
Sorted [12, 22, 25, 34, 64] -
Metric Value
Best Case O(n)
Worst Case O(n²)
Average O(n²)
Space O(1)
Stable? Yes
Algorithm
for i = 0 to n-2:
minIndex = i
for j = i+1 to n-1:
if arr[j] < arr[minIndex]: minIndex = j
swap(arr[i], arr[minIndex])
Example
Array: [64, 25, 12, 22, 11]
Pass Min Found Array After Swap
Pass 1 (i=0) 11 at index 4 [11, 25, 12, 22, 64]
Pass 2 (i=1) 12 at index 2 [11, 12, 25, 22, 64]
Pass 3 (i=2) 22 at index 3 [11, 12, 22, 25, 64]
Pass 4 (i=3) 25 at index 3 [11, 12, 22, 25, 64]
Result - [11, 12, 22, 25, 64] SORTED
Metric Value
Best Case O(n²)
Worst Case O(n²)
Space O(1)
Stable? No
Algorithm
for i = 1 to n-1:
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
Example
Array: [12, 11, 13, 5, 6]
Step Key Array State
i=1 key=11 [11, 12, 13, 5, 6]
i=2 key=13 [11, 12, 13, 5, 6]
i=3 key=5 [5, 11, 12, 13, 6]
i=4 key=6 [5, 6, 11, 12, 13]
Metric Value
Best Case O(n)
Worst Case O(n²)
Space O(1)
Stable? Yes
Algorithm
mergeSort(arr, l, r):
if l < r:
mid = (l + r) / 2
mergeSort(arr, l, mid)
mergeSort(arr, mid+1, r)
merge(arr, l, mid, r)
Example
Array: [38, 27, 43, 3]
Split: [38, 27, 43, 3]
[38, 27] [43, 3]
[38] [27] [43] [3]
Merge: [27, 38] [3, 43]
Result: [3, 27, 38, 43]
Metric Value
Best Case O(n log n)
Worst Case O(n log n)
Space O(n)
Stable? Yes
Algorithm
quickSort(arr, low, high):
if low < high:
pi = partition(arr, low, high) // pivot index
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
Metric Value
Best Case O(n log n)
Worst Case O(n²)
Average O(n log n)
Space O(log n)
Stable? No
Steps
• Build Max Heap: rearrange array so parent is always >= children
• Extract max (root) and swap with last element
• Reduce heap size by 1 and heapify the root
• Repeat until heap has 1 element
Example
Array: [4, 10, 3, 5, 1]
Build Max Heap: [10, 5, 3, 4, 1]
Swap root with last: [1, 5, 3, 4, 10] → 10 sorted
Heapify: [5, 4, 3, 1, 10]
Swap: [1, 4, 3, 5, 10] → 5 sorted
... Continue ...
Final: [1, 3, 4, 5, 10]
Metric Value
Best Case O(n log n)
Worst Case O(n log n)
Space O(1)
Stable? No
1.7 Sorting Algorithms Comparison
Algorithm Best Average Worst Space Stable
Bubble Sort O(n) O(n²) O(n²) O(1) Yes
Selection Sort O(n²) O(n²) O(n²) O(1) No
Insertion Sort O(n) O(n²) O(n²) O(1) Yes
Merge Sort O(n log n) O(n log n) O(n log n) O(n) Yes
Quick Sort O(n log n) O(n log n) O(n²) O(log n) No
Heap Sort O(n log n) O(n log n) O(n log n) O(1) No
Algorithm
linearSearch(arr, n, key):
for i = 0 to n-1:
if arr[i] == key:
return i // found at index i
return -1 // not found
Example
Array: [20, 40, 60, 10, 50] → Search for 10
Step 1: arr[0] = 20 ≠ 10
Step 2: arr[1] = 40 ≠ 10
Step 3: arr[2] = 60 ≠ 10
Step 4: arr[3] = 10 = 10 → FOUND at index 3!
Metric Value
Best Case O(1) — first element
Worst Case O(n) — last or not found
Space O(1)
Algorithm
binarySearch(arr, low, high, key):
while low <= high:
mid = (low + high) / 2
if arr[mid] == key: return mid
else if arr[mid] < key: low = mid + 1
else: high = mid - 1
return -1
Example
Sorted Array: [2, 5, 8, 12, 16, 23, 38, 45] → Search for 23
Step low high mid arr[mid] Action
1 0 7 3 12 23 > 12 → low = 4
2 4 7 5 23 23 = 23 → FOUND at 5!
Metric Value
Best Case O(1) — mid is target
Worst Case O(log n)
Space O(1)
Requirement Array must be SORTED
UNIT 2: Stack & Queue
2.1 Stack
Definition
A Stack is a linear data structure that follows the LIFO (Last In, First Out) principle. The element
inserted last is the first to be removed. Think of a stack of plates — you add and remove from the top.
Real-World Examples
• Stack of plates in a cafeteria
• Browser back button (history of visited pages)
• Undo operation in text editors
• Function call stack in programming
Stack Operations
Operation Description Time Complexity
push(x) Insert element x at top of stack O(1)
pop() Remove and return top element O(1)
peek() / top() Return top element without removing O(1)
isEmpty() Check if stack is empty O(1)
isFull() Check if stack is full (array-based) O(1)
Applications of Stack
• Expression Evaluation (Infix, Postfix, Prefix)
• Expression Conversion (Infix to Postfix/Prefix)
• Balanced Parentheses Checking
• Function call management (Recursion)
• DFS (Depth First Search) in graphs
• Backtracking algorithms
2.2 Stack – Expression Evaluation
Types of Expressions
Type Notation Example
Infix Operator between operands A+B*C
Prefix (Polish) Operator before operands +A*BC
Postfix (Reverse Operator after operands ABC*+
Polish)
Result: Postfix of A + B * C - D is A B C * + D -
2.3 Queue
Definition
A Queue is a linear data structure that follows the FIFO (First In, First Out) principle. The element
inserted first is the first to be removed. Think of people standing in a line — first person joins first,
served first.
Real-World Examples
• People waiting in a bank queue
• Print spooler (printer queue)
• CPU process scheduling
• BFS (Breadth First Search) in graphs
Queue Operations
Operation Description Time Complexity
enqueue(x) Insert element x at rear O(1)
dequeue() Remove element from front O(1)
peek() / front() Return front element without removing O(1)
isEmpty() Check if queue is empty O(1)
isFull() Check if queue is full O(1)
Queue Representation
Initially: FRONT = -1, REAR = -1
2. Circular Queue
Overcomes the limitation of linear queue. The last position wraps around to connect to the first position,
forming a circle. REAR = (REAR + 1) % MAX_SIZE.
Advantage:
• No wasted space — reuses positions freed by dequeue
• More memory efficient than linear queue
enqueue: REAR = (REAR + 1) % SIZE
dequeue: FRONT = (FRONT + 1) % SIZE
Full condition: (REAR + 1) % SIZE == FRONT
Empty condition: FRONT == REAR
4. Priority Queue
Each element has a priority. Elements with higher priority are served before lower priority elements,
regardless of insertion order.
Type Behavior
Min-Priority Queue Element with LOWEST priority value is served first
Max-Priority Queue Element with HIGHEST priority value is served first
Applications of Queue
• CPU Scheduling (Round Robin, FCFS)
• Disk Scheduling algorithms
• Breadth First Search (BFS) in graphs
• Handling requests on a single shared resource (printer, CPU)
• Simulation of real-world queues (bank, ticket counter)
UNIT 3: Trees & Graph Algorithms
3.1 Binary Tree
Definition
A Binary Tree is a hierarchical data structure where each node has at most TWO children, called the
left child and right child. The topmost node is called the root.
Key Terminology
Term Definition
Root Topmost node; has no parent
Leaf Node Node with no children
Height Length of longest path from root to leaf
Depth Distance of a node from the root
Degree Number of children a node has (max 2 in binary tree)
Subtree A node and all its descendants
Tree Traversals
Three standard traversal methods — all use recursion:
Traversal Order Result for above tree
Inorder (LNR) Left → Node → Right 4, 2, 5, 1, 6, 3, 7
Preorder (NLR) Node → Left → Right 1, 2, 4, 5, 3, 6, 7
Postorder (LRN) Left → Right → Node 4, 5, 2, 6, 7, 3, 1
BST Operations
1. Search
• Start at root
• If key == root → found
• If key < root → search left subtree
• If key > root → search right subtree
• If null → not found
2. Insertion
• Search for correct position using BST property
• Insert new node as leaf at that position
Example — Build BST from: 50, 30, 70, 20, 40, 60, 80
Insert 50: 50
Insert 30: 50
/
30
Insert 70: 50
/ \
30 70
Insert 20,40,60,80: 50
/ \
30 70
/ \ / \
20 40 60 80
Inorder traversal of this BST: 20, 30, 40, 50, 60, 70, 80 (Sorted!)
Key Property: Inorder traversal of a BST always gives SORTED output.
Algorithm Steps
1. Initialize distance of source = 0, all others = ∞
2. Add all vertices to unvisited set
3. Select unvisited vertex with minimum distance → call it 'current'
4. For each unvisited neighbor of current: calculate tentative distance = dist[current] +
edge_weight
5. If tentative distance < dist[neighbor], update dist[neighbor]
6. Mark current as visited (remove from unvisited set)
7. Repeat steps 3-6 until all vertices visited
Example Graph
Graph edges (source → dest, weight):
A → B: 4 A → C: 2
B → C: 1 B → D: 5
C → B: 1 C → D: 8 C → E: 10
D → E: 2 E → D: 3
Source = A
Step-by-Step Execution
Step Visited dist[A] dist[B] dist[C] dist[D] dist[E]
Initial {} 0 ∞ ∞ ∞ ∞
Visit A {A} 0 4 2 ∞ ∞
Visit C {A,C} 0 3 2 10 12
(min=2)
Visit B {A,C,B} 0 3 2 8 12
(min=3)
Visit D {A,C,B,D} 0 3 2 8 10
(min=8)
Visit E {A,C,B,D,E} 0 3 2 8 10
(min=10)
Metric Value
Time Complexity (Simple) O(V²)
Time Complexity (Priority Queue) O((V+E) log V)
Space O(V)
UNIT 4: Algorithm Analysis & Asymptotic Notations
4.1 What is an Algorithm?
Definition
An algorithm is a finite set of well-defined, unambiguous instructions to solve a problem or perform a
computation. It takes input, processes it, and produces output.
Space Complexity
Space complexity measures the amount of memory an algorithm uses relative to input size n.
Types of Analysis
Case Description Example
Best Case Minimum time for any input of size n Searching: element found at first
position
Worst Case Maximum time for any input of size n Searching: element at last position or
absent
Average Case Expected time over all possible Average behavior over random inputs
inputs of size n
Comparing Notations
Notation Type Condition Usage
O(g(n)) Upper Bound f(n) ≤ c·g(n) Worst case guarantee
Ω(g(n)) Lower Bound f(n) ≥ c·g(n) Best case guarantee
Θ(g(n)) Tight Bound Both above Exact behavior
o(g(n)) Strict Upper f(n) < c·g(n) f strictly slower than g
ω(g(n)) Strict Lower f(n) > c·g(n) f strictly faster than g
UNIT 5: Algorithm Design Techniques
5.1 Knapsack Problem
Problem Statement
Given n items each with a weight and value, and a knapsack with capacity W: select items to maximize
total value without exceeding capacity W.
Two Variants
Type Items Approach
0/1 Knapsack Either take whole item or leave it Dynamic Programming
Fractional Knapsack Can take fraction of an item Greedy Algorithm
Metric Value
Time Complexity O(n log n) for sorting
Space O(1)
0/1 Knapsack (Dynamic Programming)
Use a 2D table dp[i][w] = maximum value using first i items with capacity w.
Example: n=3 items, W=4
Item Weight Value
Item 1 1 1
Item 2 3 4
Item 3 4 5
DP Table dp[i][w]:
Item \ W 0 1 2 3 4
0 (no items) 0 0 0 0 0
1 (w=1,v=1) 0 1 1 1 1
2 (w=3,v=4) 0 1 1 4 5
3 (w=4,v=5) 0 1 1 4 5
Maximum value = dp[3][4] = 5 → Select Item 2 (value 4) — wait, = 5 means Item 1+2 = 1+4 = 5
Metric Value
Time Complexity O(n × W)
Space Complexity O(n × W)
Approach: Backtracking
Place queens one column at a time. For each column, try all rows. If placement is safe → move to next
column. If no row is safe → backtrack to previous column and try next row.
Safety Check
• Same row: arr[i] == arr[j]
• Same diagonal: |arr[i] - arr[j]| == |i - j|
• Same column: automatically avoided by column-by-column placement
Example: 4-Queen Problem (N=4)
Board size: 4×4
One solution: Q . . .
. . Q .
. . . Q
. Q . .
Column: 1 2 3 4
Row placed: 1 3 4 2 → arr = [1, 3, 4, 2]
Verification:
Queens at (1,1),(2,3),(3,4),(4,2)
No two share row ✓ No two share column ✓
No two share diagonal ✓ VALID SOLUTION!
N Solutions
1 1
4 2
5 10
8 92
Metric Value
Time Complexity O(N!)
Space O(N)
Algorithm Idea
Consider vertices 1, 2, ..., n one by one as intermediate vertices. For each pair (i, j), check if going
through intermediate vertex k gives a shorter path.
Initialize dist[i][j] = weight of edge (i,j), or ∞ if no direct edge
dist[i][i] = 0 for all i
Reading the final matrix: dist[i][j] gives the shortest path from vertex i to vertex j.
Metric Value
Time Complexity O(V³)
Space Complexity O(V²)
Handles Negative Weights Yes
Handles Negative Cycles No (detects them: dist[i][i] < 0)
vs Dijkstra Floyd-Warshall is all-pairs; Dijkstra is single-source