Algorithmic Complexity

Context: FIT1008_MOC, FIT2004_MOC · backbone clustering the measurement foundation — input size, the RAM cost model, time complexity, per-operation cost, and best/worst/average cases FIT2004 emphasis: distinguish total space from auxiliary space (extra beyond the input — an in-place algorithm uses auxiliary); and always quote the tightest () bound available, not just an upper bound. Input size is often bit-length — for a number , , not itself.

Quick Revision

  • 🎯 Objective: measure the resource (time/space) as a function of input size ➔ the question is scalability as .
  • 📦 Core Components: input size (often bit-length!) | RAM unit-cost steps | time complexity | case (best/worst/avg/amortised).
  • ⚡ Key Constraint: unqualified “complexity” = worst case; the RAM unit-cost assumption breaks for variable-size keys ().

📝 Core

1. The Resource Question

  • What it measures ➔ how cost grows with input size — time (elementary ops) or space (peak memory); FIT1008 focuses on time.
  • Function of ➔ stated as , not a single number, because we care how it scales.
  • Time–space trade-off ➔ extra memory buys speed (memoisation, hash tables) and vice-versa.

2. Input Size (“Big” Defined)

  • Type-dependent ➔ collection’s element count | string’s chars | graph’s and .
  • Bit-length trap ➔ a number has size , not ; halving to therefore takes steps, i.e. .
  • Pseudo-polynomial ➔ a loop running times is in true size (Knapsack , still NP-hard).
  • A BOUNDED parameter is a constant ➔ if the spec caps a parameter (, ), that parameter contributes and vanishes from the bound — the cap makes it independent of input size, not merely small.
  • Which symbols are free ➔ before quoting a bound, list which parameters can grow without limit; a bound may only be expressed in those. The output size can be one of them ➔ Output-Sensitive Complexity.

3. Running Time & RAM Model

  • AbstractionRandom-Access Machine — each elementary op = 1 unit, random access (ignores compiler/machine).
  • Portability ➔ step count is machine-independent ⟹ "" portable, “3 ms” not.
  • Boundary ➔ breaks for arbitrary-precision arithmetic / external-memory effects.
  • Declare the unit-cost assumption ➔ ” is ” holds only for machine-word operands; on values whose bit-length grows with an addition costs ➔ iterative Fibonacci is word operations but bit operations, since occupies bits (see Fibonacci Sequence, Recursion).

4. Time Complexity & Step Cost

  • Counting rules ➔ statement | sequence sums | if = test + branch | loop = body × iters | recursion = recurrence.
  • CompEq factor ➔ a step is only for fixed-size keys; length- strings ⟹ .
  • swap is ➔ 3 copies; choose a sort minimising the expensive op.

5. Best / Worst / Average Case

  • Definitions ➔ at fixed : , , , with .
  • Best ≠ worst only on short-circuit ➔ requires an if/break/early return, else best=worst (selection sort).
  • Average ≠ amortised ➔ average needs a distribution; amortised is a worst-case-sequence guarantee with no probability.

6. Space: Total vs Auxiliary (FIT2004 quoting standard)

  • The lecture’s splitspace complexity input space auxiliary space; the two are reported separately because only the second is the algorithm’s choice.
  • Total space ➔ input plus everything allocated ⟹ always for an -element input, so it never discriminates between algorithms.
  • Auxiliary spaceextra beyond the input — the number quoted in a complexity table; in-place auxiliary.
  • The three iterative reference casesfind_min(arr) scans and keeps one variable ⟹ input , auxiliary , in-place · build_list(n) takes a number and allocates an -slot array ⟹ input , auxiliary · iterative binary_search(arr, target) ⟹ input , auxiliary .
  • Allocating output is auxiliary toobuild_list does no recursion and still costs — auxiliary space is any memory beyond the input, not just the call stack.
  • Recursion stack counts ➔ auxiliary space max live frame chain, i.e. frame size — sibling calls run sequentially, so only ONE root-to-leaf path is live at a time (never ); worked per algorithm in Analysing Recursive Algorithms (Time and Auxiliary Space).
  • Depth is the discriminator ➔ balanced recursion frames (Quick Sort with the smaller side recursed first) vs peeling one element frames — the same split that decides time in Divide and Conquer.
  • Shrinking frames sum, not multiply ➔ frames of size total , not — by the bound in Geometric Series.
  • Time auxiliary space — always ➔ memory must be allocated and written before it counts as used, and each cell costs at least one step ⟹ an algorithm quoting auxiliary cannot be in time. A -time algorithm claiming auxiliary is a marking error somewhere.
  • Tightest bound ➔ quote when best worst; reserve for a genuine upper-bound-only claim.

⚙️ Core Implementation

🔹 Step-counting & the input-size gotcha

🔹 Cost of a step & best/worst short-circuit

⚖️ Core Decision Matrix

(Best / Average / Worst time, with the worst-case trigger.)

AlgorithmBestAverageWorstTrigger of worst
Bubble Sort IIreverse-sorted
Selection Sortalways (no short-circuit)
Insertion Sortreverse-sorted
Quick Sortmin/max pivot
Hash Tableall keys collide

When It Flips: quote worst for guarantees (real-time/adversarial), average for typical (quicksort, hashing), best rarely. Average ≠ amortised — average assumes a distribution (fails on skewed inputs); amortised is a hard worst-case-sequence guarantee with no probability.

📊 Exam Execution Trace

Manual Execution Trace

Costing code shapes to a closed form:

Step / StateCode ShapeContribution to
0 (Init)simple statement
1sequencesum of costs
2loop body
3fixed loop factor
4recursive calla term in a recurrence

Applied Exercise

Problem: Show why an Knapsack DP is pseudo-polynomial, not polynomial. Derivation Proof / Hand-Calculation Walkthrough:

Final Extracted Output: polynomial in the value but exponential in its bit-length ⟹ pseudo-polynomial (why Knapsack stays NP-hard).

✍️ Practice

🧠 Active Recall