0% found this document useful (0 votes)
6 views5 pages

Algorithms Detailed

Uploaded by

Showrav Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views5 pages

Algorithms Detailed

Uploaded by

Showrav Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Algorithms — Detailed Guide

Contents: Linear Search, Binary Search, Bubble Sort, Insertion Sort, Selection Sort, Quick Sort, Merge Sort,
Knapsack (Fractional & 0/1), Job Sequencing (Deadlines), Kruskal's MST

1. Linear Search
What: A simple search that checks each element of the array in order until it finds the target or reaches the end.
Intuition: Walk from left to right; stop when you find the item.
Use-case: Unsorted arrays or small lists; simple and predictable.
Pseudocode (iterative):
for i from 0 to n-1:
if A[i] == target:
return i # found
return -1 # not found
Trace example: A = [7, 2, 9, 4], target = 9
Step 1: i=0, compare 7 with 9 -> not equal
Step 2: i=1, compare 2 with 9 -> not equal
Step 3: i=2, compare 9 with 9 -> equal -> return 2

2. Binary Search
What: Fast search for sorted arrays. Repeatedly split the search interval in half.
Intuition: Compare target to middle element; discard half where target cannot lie.
Requirement: The array must be sorted.
Pseudocode (iterative):
low = 0; high = n - 1
while low <= high:
mid = (low + high) // 2
if A[mid] == target: return mid
elif A[mid] < target: low = mid + 1
else: high = mid - 1
return -1
Trace example: A = [1, 3, 5, 7, 9], target = 7
Step: low=0, high=4 -> mid=2, A[2]=5 (<7) -> low=3
Step: low=3, high=4 -> mid=3, A[3]=7 -> found at index 3

3. Bubble Sort (optimized)


What: Simple comparison sort that repeatedly swaps adjacent elements when out of order.
Intuition: Large values 'bubble' to the end after each pass. Can stop early if a pass makes no swaps.
Characteristics: Stable, in-place, easy to implement but O(n^2) time in general.
Pseudocode (optimized):
for pass from 1 to n-1:
swapped = false
for i from 0 to n-pass-1:
if A[i] > A[i+1]:
swap A[i], A[i+1]
swapped = true
if not swapped: break
Trace example: A = [4, 2, 3, 1]
Pass 1: compare (4,2) -> swap -> [2,4,3,1]
compare (4,3) -> swap -> [2,3,4,1]
compare (4,1) -> swap -> [2,3,1,4]
Pass 2: compare (2,3) -> ok
compare (3,1) -> swap -> [2,1,3,4]
Pass 3: compare (2,1) -> swap -> [1,2,3,4] -> sorted

4. Insertion Sort
What: Builds the final sorted array one item at a time by inserting elements into the correct place in the sorted
prefix.
Intuition: Like sorting playing cards in your hands — pick one and insert it into the right position.
Characteristics: Stable, in-place, works well for small or nearly-sorted data.
Pseudocode:
for i in range(1, n):
key = A[i]
j = i - 1
while j >= 0 and A[j] > key:
A[j+1] = A[j]
j = j - 1
A[j+1] = key
Trace example: A = [4, 2, 3, 1]
i=1: key=2, shift 4 -> [2,4,3,1]
i=2: key=3, shift 4 -> [2,3,4,1]
i=3: key=1, shift 4,3,2 -> [1,2,3,4]

5. Selection Sort
What: Repeatedly selects the minimum element from the unsorted portion and swaps it to the front.
Intuition: Find the smallest remaining item and put it in the next slot.
Characteristics: Not stable by default, in-place, performs the same number of comparisons regardless of input.
Pseudocode:
for i from 0 to n-2:
minIndex = i
for j from i+1 to n-1:
if A[j] < A[minIndex]:
minIndex = j
swap A[i], A[minIndex]
Trace example: A = [4, 2, 3, 1]
i=0: minIndex=3 (value 1) -> swap -> [1,2,3,4]
i=1: already smallest at index 1 -> no swap -> [1,2,3,4]

6. Quick Sort (Lomuto partition)


What: Fast divide-and-conquer sort. Choose a pivot, partition array, sort partitions recursively.
Intuition: Put pivot in its final position; everything left is <= pivot and right is > pivot, then sort subarrays.
Characteristics: Average O(n log n), worst O(n^2) for bad pivots — use random pivot to avoid worst-case. Not
stable by default.
Pseudocode (Lomuto partition):
function partition(A, low, high):
pivot = A[high]
i = low - 1
for j = low to high - 1:
if A[j] <= pivot:
i = i + 1
swap A[i], A[j]
swap A[i+1], A[high]
return i+1

function quicksort(A, low, high):


if low < high:
p = partition(A, low, high)
quicksort(A, low, p-1)
quicksort(A, p+1, high)
Trace example (partition step): A = [5, 2, 9, 1, 5, 6], pivot = 6
Initial: low=0, high=5, pivot=6, i=-1
j=0: A[0]=5 <=6 -> i=0 swap A[0]<->A[0] -> [5,2,9,1,5,6]
j=1: A[1]=2 <=6 -> i=1 swap -> [5,2,9,1,5,6]
j=2: A[2]=9 >6 -> no change
j=3: A[3]=1 <=6 -> i=2 swap A[2]<->A[3] -> [5,2,1,9,5,6]
j=4: A[4]=5 <=6 -> i=3 swap A[3]<->A[4] -> [5,2,1,5,9,6]
After loop swap A[i+1]<->A[high] -> swap A[4] and A[5] -> [5,2,1,5,6,9]
Pivot index returned = 4

7. Merge Sort
What: Stable divide-and-conquer sort that splits array in halves, sorts each half, and merges them.
Intuition: Recursively split until single elements, then merge small sorted lists into bigger sorted lists.
Characteristics: O(n log n) worst/avg/best, stable; requires O(n) extra memory to merge.
Pseudocode:
function merge_sort(A):
if len(A) <= 1: return A
mid = len(A) // 2
left = merge_sort(A[:mid])
right = merge_sort(A[mid:])
return merge(left, right)

function merge(left, right):


result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
extend result with remaining elements
return result
Trace example: A = [4,1,3,2]
Split -> [4,1] and [3,2]
Left [4,1] -> split [4] and [1] -> merge -> [1,4]
Right [3,2] -> split [3] and [2] -> merge -> [2,3]
Merge [1,4] and [2,3] -> [1,2,3,4]

8. Knapsack Problem
Problem: Given items with values and weights and a capacity W, select items to maximize total value without
exceeding W.
Two main variants: Fractional (items divisible) — greedy; 0/1 (items indivisible) — dynamic programming.
Fractional (greedy) outline:
1. For each item compute ratio = value / weight
2. Sort items by ratio descending
3. Take items in that order; if next item doesn't fit fully, take fractional part to fill capacity

0/1 Knapsack (DP) outline:


Let dp[i][w] = max value using first i items and capacity w
Base: dp[0][*] = 0
For i from 1..n:
for w from 0..W:
if weight[i] <= w:
dp[i][w] = max(dp[i-1][w], value[i] + dp[i-1][w-weight[i]])
else:
dp[i][w] = dp[i-1][w]
Fractional example:
Items: (v=60,w=10), (v=100,w=20), (v=120,w=30), Capacity W=50
Ratios: 6.0, 5.0, 4.0 -> take item1 (w=10,v=60), take item2 (w=20,v=100), remaining capacity 20 -> ta

0/1 DP example (small):


Items: (v=60,w=10), (v=100,w=20), (v=120,w=30), W=50
DP table (rows items 0..3, cols 0..50) compute dp[3][50] = 220 (choose items 2 and 3 or 1+3? actual o

9. Job Sequencing with Deadlines (maximize profit)


Problem: Jobs have deadlines and profits; each job takes unit time. Schedule to maximize profit while meeting
deadlines.
Greedy approach works because scheduling the highest-profit jobs first and placing them as late as possible
leaves room for other jobs.
Pseudocode (greedy):
Sort jobs by profit descending
let maxDeadline = max(job.deadline)
create slots[1..maxDeadline] initialized to empty
for each job in sorted order:
for t from job.deadline down to 1:
if slots[t] is empty:
slots[t] = job
break
Example: Jobs = [(J1,d=2,p=100), (J2,d=1,p=19), (J3,d=2,p=27), (J4,d=1,p=25)]
Sort by profit: J1(100), J3(27), J4(25), J2(19)
Slots size = 2 -> try J1 -> place in slot 2; J3 -> place in slot 1; J4 -> no slot; J2 -> no slot
Scheduled jobs: J1 (slot2), J3 (slot1). Total profit = 127

10. Kruskal's Minimum Spanning Tree (MST)


Problem: Given a connected weighted graph, find a subset of edges that connects all vertices with minimum total
weight and no cycles.
Idea: Sort edges by increasing weight and add them if they connect two previously disconnected components
(Union-Find to detect cycles).
Pseudocode:
Sort edges by weight ascending
initialize DSU (disjoint set) for all vertices
MST = empty set
for each edge (u, v, w) in sorted edges:
if find(u) != find(v):
add edge to MST
union(u, v)
return MST
Small example:
Vertices: {A,B,C,D}
Edges sorted by weight: (A,B,1), (C,D,2), (A,C,3), (B,D,4), (A,D,5)
Process:
- Take (A,B,1): union A,B -> MST={(A,B,1)}
- Take (C,D,2): union C,D -> MST+={(C,D,2)}
- Take (A,C,3): find(A) != find(C) -> union -> MST+={(A,C,3)} ; now all vertices connected -> stop (M

Complexities Summary (quick):


Searches: Linear O(n), Binary O(log n)
Sorts: Bubble O(n^2), Insertion O(n^2)/O(n) best, Selection O(n^2), Quick O(n log n) avg, Merge O(n l
Knapsack: Fractional O(n log n), 0/1 DP O(n*W)
Kruskal: O(E log E)

Generated with detailed step-by-step explanations, pseudocode, and worked examples.

You might also like