Binary Search

Context: FIT1008_MOC, FIT2004_MOC · the decrease-and-conquer search · contrast with Linear Search · powers index in SortedArrayList FIT2004 emphasis: the canonical best worst example — an early return exists, so / cannot be collapsed into one ; it is the locate half of Output-Sensitive Complexity; and W2 makes it the unit’s termination counter-exampleInvariant.

Quick Revision

  • 🎯 Objective: find a target in a sorted array by halving the window ➔ , exponentially faster than linear search.
  • 📦 Core Components: window ➔ probe midpoint ➔ discard half.
  • ⚡ Key Constraint: needs order + random access (no LinkList); and the window must strictly shrink — the obvious lo = mid formulation loops forever.

📝 Core

1. The Algorithm (Halve the Window)

  • Mechanism ➔ keep window , probe midpoint, discard half (match / keep / keep ).
  • Preconditionsorder (so “too high/low” is meaningful) + random access to the midpoint.

2. Why (the Invariant)

  • Halving ➔ each pass is and halves the window ⟹ passes.
  • Loop invariantif the key exists in array[0…N], it exists in array[lo…hi] — the if/else is exactly what preserves it, and it is deliberately the weakest statement that implies the postcondition.
  • Best worst, and why ➔ the return mid short-circuits ⟹ best (target is the first midpoint), worst (target absent, window shrinks to empty). Contrast Linear Search’s recursive form, which has no early exit on a miss.

3. The Termination Bug (why lo = mid hangs)

  • The naive formwhile lo < hi: mid = (lo+hi)//2; if key >= array[mid]: lo = mid else: hi = mid — no early return, because lo is reused as the answer index.
  • The stall ➔ at : , so lo = mid sets no measure decreases, the guard stays true, the loop spins forever.
  • The fixwhile lo < hi - 1: since hi is exclusive (initialised to len(array)), the search space is allowed to shrink to size and then exit, with lo holding the answer index.
  • Why it matters beyond the exam ➔ a non-terminating branch is input-dependent, so it survives testing; in FIT2004 assignments the marking harness kills the thread on timeout and the mark is lost.

4. Boundary Search (the range-reporting entry point)

  • Search for the boundary, not the value ➔ to report everything in , binary-search the smallest element itself need not be in the array.
  • Then scan ➔ walk forward printing until an element for reported items ➔ Output-Sensitive Complexity.

⚙️ Core Implementation

🔹 index via binary search (inclusive high, early return)

🔹 Boundary form (exclusive hi, no early return)

⚖️ Core Decision Matrix

AspectComplexityWhy
Time — besttarget is the first midpoint
Time — worst/avgwindow halves each pass
Space (iterative)three indices
Space (recursive)call stack

When It Flips: vs Linear Search () always better; vs Hash Table ( expected but unordered) binary search keeps order for predecessor/successor/range. A balanced Binary Tree is "binary search made dynamic" — search and insert/delete, which a sorted array can't.

📊 Exam Execution Trace

Manual Execution Trace

Search 15 in [2,5,8,12,15,23,42,50]:

Step / StateTrigger Op[lo, hi]mid / array[mid]Action
0 (Init)init[0, 7]
1probe[0, 7]3 / 1212 < 15 → lo = 4
2probe[4, 7]5 / 2323 > 15 → hi = 4
3probe[4, 4]4 / 15match → return 4

Applied Exercise

Problem: Derive the bound. Derivation Proof / Hand-Calculation Walkthrough:

Final Extracted Output: halving ⟹ passes of — vs linear search’s .

🧠 Active Recall