Asymptotic Analysis, Recurrence Relations, Master Theorem & Sorting
Unit 4 formalises algorithm efficiency independent of physical hardware using the Word RAM model, asymptotic growth classes (), closed-form recurrence derivations, the Master Theorem, and structural design paradigms.
word ram model, basic operations & big-o bounds.
In theoretical computer science, algorithms are analysed on the Word RAM (Random Access Machine) model: a hypothetical computer where memory consists of an unbounded array of words, and primitive operations (arithmetic , logical comparisons, array indexing, and variable assignment) on word-sized operands execute in constant time.
Rather than counting every machine instruction, we identify the Basic Operation—the most significant operation inside the deepest loop (such as key comparison in sorting/searching, or arithmetic multiplication in matrix algorithms)—and express its count as a growth function of the input size across Best-Case, Worst-Case, and Average-Case inputs. Note that in the HESS notes:
- Growth Function Restrictions: Any valid complexity growth function must satisfy two mathematical domain/range restrictions: (input sizes are positive integers) and (step counts are non-negative).
- Average-Case Complexity Warning: The Average-Case complexity is determined using probability and statistical expectation over the distribution of all possible inputs of size —it is not simply the arithmetic mean of the Best Case and Worst Case!
| ALGORITHM CLASS | BASIC OPERATION |
|---|---|
| Sorting / Searching | Key Comparison (if A[i] == A[j]) |
| Matrix Multiplication | Float / Int Multiplication (M[i][j] = a * b) |
| Graph Traversal | Visiting / Expanding a Node |
| PROGRAM CONSTRUCT | SPACE COMPLEXITY |
|---|---|
| Initialising / Assigning Variable | |
| Storing Array / List / Stack / Queue of size | |
| Iterative Function Calls | |
| Nested Recursive Function Calls | (Call Stack Frames) |
- Big-O (): Formal upper bound. There exist positive constants and such that for all .
- Big-Omega (): Formal lower bound. There exist positive constants and such that for all .
- Big-Theta (): Formal tight bound. and (bounded both above and below by for all ).
- Total Space Complexity: Total memory cells consumed by the algorithm, including the input data itself.
- Auxiliary Space Complexity: Extra temporary working memory allocated beyond the input data (e.g., call-stack frames in recursion, or temporary subarrays in Merge Sort).
- In-Place Algorithm: An algorithm that requires only (or stack) auxiliary space, modifying the input container directly.
solving recurrence relations: iteration & telescoping.
The running time of a recursive algorithm is naturally expressed as a recurrence relation consisting of a recursive step (for ) and a base case (e.g., ). Note that by Church-Turing equivalence, every recursive function can be converted into an iterative function (using an explicit loop/stack) and vice versa. In VCE Algorithmics, recurrences that are not in Master Theorem form (such as decrease-by-one recurrences) are solved into closed form via Iteration (Backward/Forward Substitution) or Telescoping Sums.
Essential Closed-Form Summation Identities
Substitute backward for steps:
Set :
Expand the recurrence step-by-step for steps until reaching :
Set :
Rearrange as and sum from to :
Summing the left and right sides telescopes to:
Constant Telescoping (): Writing for and summing cancels all interior terms:
Binary Search by Iteration (): After halvings ():
the master theorem & strassen's multiplication.
For divide-and-conquer algorithms that divide a problem of size into subproblems, each of size (where ), and spend work splitting and merging (where ):
| ALGORITHM | RECURRENCE | PARAMETERS () | COMPARISON | CLOSED-FORM BOUND |
|---|---|---|---|---|
| Binary Search | (Case 2) | |||
| Merge Sort / Quick Sort (Best) | (Case 2) | |||
| Binary Tree Traversal | (Case 3) | |||
| Naive D&C Matrix Multiply | (Case 3) | |||
| Strassen's Matrix Multiply | (Case 3) |
The Master Theorem does not apply when: (1) the problem size decreases by subtraction rather than division (e.g., ), (2) subproblems have uneven split sizes (e.g., ), (3) is not a constant, or (4) the non-recursive work is non-polynomial (e.g., ). When the Master Theorem fails, the HESS notes specify three fallback methods: the Recursion Tree Method (summing work level-by-level), the Substitution Method (guessing the bound and proving by mathematical induction), or the general Akra–Bazzi Theorem (for uneven divide-and-conquer splits).
binary search & loop invariant induction proof.
Binary Search locates a target value in a sorted array by comparing against the midpoint and discarding half of the remaining array each step.
In the HESS notes, Binary Search is rigorously classified as a Decrease-and-Conquer algorithm (specifically decrease-by-a-constant-factor) rather than Divide-and-Conquer, because it only recurses on one half () and discards the other without any merge step.
Algorithm BinarySearch(A[0..n-1], target):
min <- 0
max <- n - 1
While min <= max do:
mid <- floor((min + max) / 2)
If A[mid] == target then:
Return mid
Else If A[mid] < target then:
min <- mid + 1
Else:
max <- mid - 1
End If
End While
Return -1 // Not found
End Algorithm Invariant : If target is present in the sorted array , then at step , .
- Base Case (): Before the first iteration, and . Since is sorted across , if
targetis in , then holds. - Inductive Step (): Assume . Let :
• If , because is sorted, . Setting preserves .
• If , because is sorted, . Setting preserves . - Termination: Since the interval size strictly decreases each step, the loop must terminate either by finding or exhausting .
algorithm design paradigms & greedy proof methods.
| PARADIGM | CORE MECHANISM | CANONICAL EXAMPLES |
|---|---|---|
| Brute-Force (Exhaustive Search) | Generates and evaluates every candidate solution in the state space directly from the problem statement. | Linear Search, Selection Sort, Exhaustive TSP (), 0-1 Knapsack Power Set (). |
| Greedy Paradigm | Builds a solution step-by-step by making the locally optimal choice at each stage, never reconsidering past choices. | Prim's MST, Kruskal's MST, Dijkstra's SSSP, Greedy Graph Colouring, Coin Change (canonical denominations). |
| Decrease-and-Conquer | Reduces a problem instance to a single smaller instance (by a constant , constant factor , or variable size) and extends the solution. | Binary Search (), Insertion Sort (), DFS/BFS, Euclidean GCD (variable decrease). |
| Divide-and-Conquer | Splits a problem into multiple independent subproblems of roughly equal size, solves them recursively, and merges the results. | Merge Sort, Quick Sort, Binary Tree Traversal, Strassen's Matrix Multiplication, Closest Pair of Points. |
| Dynamic Programming (DP) | Optimises problems with overlapping subproblems and optimal substructure by caching subproblem solutions (bottom-up tabulation or top-down memoization). | Fibonacci (tabulated), Bellman-Ford, Warshall's, Floyd-Warshall's, 0-1 Knapsack DP. |
| Backtracking | Optimised brute-force search over a state-space tree that prunes (abandons) partial solutions as soon as they violate constraints. | -Queens Problem, Exact Graph Colouring, Hamiltonian Circuit search, Sudoku solver. |
Proving Greedy Algorithms Correct (The Two 4-Step HESS Proof Frameworks)
Because greedy algorithms do not always yield globally optimal solutions (for example, greedy coin-changing fails for coins with target , picking instead of ), proving a greedy algorithm optimal requires one of two formal 4-step proof frameworks from the HESS notes:
- Define Solutions: Let be the greedy solution and be an arbitrary optimal solution.
- Define Measure: Define a quantitative progress measure and after step .
- Prove Greedy Stays Ahead: Prove by mathematical induction on that (or for minimisation) for all .
- Prove Optimality: Deduce (often by contradiction) that because greedy stays ahead at termination, must be globally optimal.
- Define Solutions: Let be the greedy solution and be a hypothetical optimal solution.
- Compare Solutions: Assume and identify the first component where differs from .
- Exchange Pieces: Swap the differing element in with the greedy choice from to form , proving remains valid and no worse in cost than .
- Iterate: Repeat the exchange step until is transformed into without degrading optimality, proving is optimal.
Algorithm BackTrack(attempt, possible_options):
If attempt is a complete solution then:
Return attempt
End if
For each option in possible_options do:
If option is valid for attempt then:
add option to attempt
result <- BackTrack(attempt, updated_options)
If result != failure then:
Return result
End if
remove option from attempt // Backtrack!
End if
End do
Return failure
End Algorithm merge sort & quick sort analysis.
Algorithm MergeSort(A[0..n-1]):
Function Merge(Al[0..p-1], Ar[0..q-1], A[0..p+q-1]):
i <- 0; j <- 0; k <- 0
While i < p and j < q do:
If Al[i] <= Ar[j] then:
A[k] <- Al[i]; i <- i + 1
Else:
A[k] <- Ar[j]; j <- j + 1
End If
k <- k + 1
End While
If i == p then:
Copy Ar[j..q-1] to A[k..p+q-1]
Else:
Copy Al[i..p-1] to A[k..p+q-1]
End If
End Function
If n > 1 then:
mid <- floor(n / 2)
Copy A[0..mid-1] to Al
Copy A[mid..n-1] to Ar
MergeSort(Al)
MergeSort(Ar)
Merge(Al, Ar, A)
End If
End Algorithm Algorithm Quicksort(A, min, max):
Function Partition(A, min, max):
p <- min
piv <- A[p]
i <- min; j <- max
Do:
While i < max and A[i] <= piv do:
i <- i + 1
End While
While j >= min and A[j] > piv do:
j <- j - 1
End While
Swap A[i] <-> A[j]
While i < j
// Undo last swap when pointers crossed
Swap A[i] <-> A[j]
// Place pivot into final sorted position j
Swap A[p] <-> A[j]
Return j
End Function
If min < max then:
s <- Partition(A, min, max)
Quicksort(A, min, s - 1)
Quicksort(A, s + 1, max)
End If
End Algorithm Key Comparison Analysis: Merge Sort vs Quick Sort
- Merge Sort ( in ALL cases & Bottom-Up Runs): Splitting into and creates two subproblems of size . In the best case (all elements in are smaller than all elements in ),
Mergeperforms key comparisons. In the worst case (interleaved largest and second-largest elements),Mergeperforms comparisons. In both cases, by Master Theorem Case 2. Merge Sort is stable (becauseAl[i] <= Ar[j]gives priority to the left element) and not in-place ( auxiliary array space). Alternatively, Bottom-Up Merge Sort avoids recursion by treating the input array as sorted 1-element subarrays (called runs) and iteratively merging adjacent runs of size . - Quick Sort Worst Case () vs Average Case (): When the pivot is chosen as the first element and the array is already sorted (or reverse sorted), every partition splits elements into an empty subarray of size and a subarray of size , degenerating Quick Sort from divide-and-conquer into decrease-by-one: . In the Average Case, random pivot splits require recursive levels and key comparisons.
- Quick Sort Optimisations (HESS Notes):
1. Random Pivot Selection or Median-of-Three Partitioning: Choose the median of , , and as the pivot (swapping the largest of the three candidates intoA[max]), preventing degeneration on sorted inputs.
2. Hybrid Insertion Sort Cutoff (QuickAlmostSort+InsertionSort): Stop Quick Sort recursion when subarray size is (lo + 10 < hi), leaving small partitions nearly sorted, and finish with a single pass ofInsertionSortover the entire array.
Algorithm Sort(A[lo..hi]):
Function QuickAlmostSort(A[lo..hi]):
If lo + 10 < hi then:
s <- Partition(A[lo..hi])
QuickAlmostSort(A[lo..s - 1])
QuickAlmostSort(A[s + 1..hi])
End if
End Function
QuickAlmostSort(A[lo..hi])
InsertionSort(A[lo..hi])
End Algorithm Self-Check: Solve the recurrence relation and ().
1. For , apply the Master Theorem with . Since (Case 2), .
2. For , the Master Theorem does not apply (subtraction ). Using backward substitution: . Setting yields .