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 collapse into one ; it is the locate half of Output-Sensitive Complexity; and W3 makes it the unit’s termination counter-example βž” Invariant.

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 ).
  • Preconditions βž” order (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 invariant βž” if 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 implying the postcondition.
  • Best worst, and why βž” the return mid short-circuits ⟹ best (target is the first midpoint), worst (target absent). Contrast Linear Search’s recursive form, which has no early exit on a miss.

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

  • The naive form βž” while 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 is a no-op ⟹ no measure decreases, the guard stays true, the loop spins forever.
  • The fix βž” while lo < hi - 1: with hi exclusive, the space may shrink to size and exit, lo holding the answer index.
  • Why it matters beyond the exam βž” a non-terminating branch is input-dependent, so it survives testing; the assignment 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 present.
  • 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 queries and in-order iteration. A balanced Binary Tree is "binary search made dynamic" β€” search and insert/delete, which a sorted array ( inserts) cannot.

πŸ“Š 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.

Final Extracted Output: halving ⟹ passes of ⟹ β€” vs Linear Search’s , i.e. ~20 vs 1,000,000 passes on a million elements.

🧠 Active Recall