Ran Wei/CS Series/05
中文
Computer Science Fundamentals — Ran Wei

Module 05: Algorithms and efficiency

Compare algorithms by their contracts, invariants and growth rates. Implement binary search and insertion sort, then measure defined operations.

≈ 5 hours4 sessions2 labs8 exercises6 quiz questions

By the end you can

  • State preconditions for binary search.
  • Use invariants to justify sorting.
  • Distinguish O, Ω and Θ.
  • Count time and auxiliary space.
  • Compare input-dependent cases.

Before you start

Recommended modules: 03, 04.

Know loops, ordered lists and induction. log₂ n denotes the number of binary halvings needed to reduce n to one.

Contents

Study plan

5 hours

Four 75-minute sessions including practice. Allow longer for extensions or unfamiliar prerequisites. Progress is saved locally and shared between language editions.

Session 175 min
Concepts and worked examples
Session 375 min
Apply and extend
1

A cost model and growth rates

Choose input size and an operation before counting. For n constant-sized keys, linear search needs at most n equality checks. O(g(n)) is an asymptotic upper bound up to a constant after some threshold; Ω is a lower bound and Θ is both. A function 3n+7 is Θ(n), because constants and fixed terms do not change large-n growth. Saying O(n²) can be true but loose for that function. These are mathematical bounds, not timings or automatically worst-case claims: state which case you analyse.

Check your understanding

Is 3n+7 also O(n²)?

Worked solution

Yes, but Θ(n) is the tighter description.

2

Linear and binary search

Binary search requires sorted keys and efficient indexed access. Maintain a half-open interval [lo,hi), initially [0,n). Inspect mid=(lo+hi)//2. To find the first matching position, advance lo past mid if the key is smaller; otherwise move hi to mid, keeping possible equal keys on the left. When lo=hi, check the insertion position for equality. Each probe removes roughly half the candidates, giving O(log n) probes. Sorting an unsorted list before one query can cost more than a single linear scan.

Check your understanding

Why keep hi=mid when equal rather than returning immediately?

Worked solution

To retain earlier duplicate matches.

3

Insertion sort and invariants

Before iteration i, the prefix [0,i) is sorted and contains exactly the original prefix's items. Take item i as key, shift larger preceding items right, and insert the key into the gap. This preserves the invariant and reaches a sorted whole list. Using > rather than >= for shifts preserves equal-key order, making the sort stable. Already sorted input takes n−1 key comparisons; reverse input takes 1+…+(n−1)=n(n−1)/2. A copied-input implementation also allocates an n-entry output.

Check your understanding

How many comparisons on reverse input of length 5?

Worked solution

1+2+3+4=10.

4

Sorting choices and lower bounds

Merge sort splits, sorts halves and merges in linear work, giving Θ(n log n) comparisons in its usual worst-case analysis and O(n) merge storage. Quicksort partitions around a pivot: typical average work is Θ(n log n), but poor pivots can give Θ(n²). A comparison-based sorter distinguishing n! permutations needs Ω(log₂(n!))=Ω(n log n) comparisons in the worst case. Counting sort can beat this bound only by using restricted integer keys and extra structure, so it does not contradict the comparison-model bound.

Check your understanding

Does counting sort refute the comparison-sort lower bound?

Worked solution

No; it uses key structure beyond comparisons.

5

Space, cases and honest measurements

Separate input storage, output storage and auxiliary working space. Iterative binary search needs O(1) auxiliary state, while a recursive version consumes O(log n) stack space. Best, worst and average cost refer to different input assumptions; an average needs a distribution. Benchmarks answer practical questions but must use equivalent outputs, comparable data and repeated runs. Operation counts reveal growth; timings reveal constants and environment. Neither replaces correctness checks.

Check your understanding

What assumption is needed to claim an average search cost?

Worked solution

A probability distribution over targets and inputs.

6

Common misconceptions

  • O is an upper bound, not automatically a tight bound.
  • Sorting costs must be counted when comparing whole workflows.
7

Lab setup

Download each script and run it in a terminal with Python 3.11 or later: python m05_search.py. On Windows, py -3 is an alternative; on some systems use python3. The labs use only the standard library. Predict the result before running, then complete the variations. Run without -O so assertions remain enabled. Outputs below were captured by the builder. Code and output are identical in both language editions.

8

Lab 1 — Binary search bounds

Trace lo and hi by hand before running. probes counts interval probes; the final equality check is separate.

Download m05_search.py

"""Binary search maintains a half-open candidate interval [lo, hi)."""
def binary_search(items, target):
    lo, hi, probes = 0, len(items), 0
    while lo < hi:
        mid = (lo + hi) // 2
        probes += 1
        if items[mid] < target:
            lo = mid + 1
        else:
            hi = mid
    found = lo if lo < len(items) and items[lo] == target else -1
    return found, probes

for size in [0, 1, 8, 16, 32]:
    items = list(range(size))
    found, probes = binary_search(items, size)
    assert found == -1
    print(f"n={size:2}, absent insertion point={size:2}, probes={probes}")
assert binary_search([1, 2, 2, 4], 2)[0] == 1
assert binary_search([], 1) == (-1, 0)
print("duplicate case returns first match")
Captured output
n= 0, absent insertion point= 0, probes=0
n= 1, absent insertion point= 1, probes=1
n= 8, absent insertion point= 8, probes=3
n=16, absent insertion point=16, probes=4
n=32, absent insertion point=32, probes=5
duplicate case returns first match
  1. Search each value in a 16-entry list.
  2. Try [2,1] and explain the violated assumption.
  3. Change hi=mid to hi=mid−1 and find a missed boundary.
Worked solution

Every present value must return its index. [2,1] is unsorted, so the contract no longer applies. hi=mid−1 mixes closed and half-open conventions; [1,2] searching 2 can be lost. Keep one interval convention throughout.

9

Lab 2 — Sort and count

Check sorted output for empty, duplicate, sorted and reversed inputs.

Download m05_sort.py

"""Insertion sort counts key comparisons, not elapsed seconds."""
def insertion_sort(values):
    result = values.copy()
    comparisons = 0
    for i in range(1, len(result)):
        key, j = result[i], i - 1
        while j >= 0:
            comparisons += 1
            if result[j] <= key:
                break
            result[j + 1] = result[j]
            j -= 1
        result[j + 1] = key
    return result, comparisons

for values in [[], [1], [1, 2, 3, 4], [4, 3, 2, 1], [2, 1, 2]]:
    result, count = insertion_sort(values)
    assert result == sorted(values)
    print(values, "->", result, "comparisons:", count)
Captured output
[] -> [] comparisons: 0
[1] -> [1] comparisons: 0
[1, 2, 3, 4] -> [1, 2, 3, 4] comparisons: 3
[4, 3, 2, 1] -> [1, 2, 3, 4] comparisons: 6
[2, 1, 2] -> [1, 2, 2] comparisons: 2
  1. Run reversed lengths 8 and 16.
  2. Track original positions of equal keys.
  3. Explain the memory cost of values.copy().
Worked solution

Reverse counts are 28 and 120, from n(n−1)/2. Equal keys are not moved past one another by the <= stop condition. Copying adds Θ(n) output storage even though the insertion procedure uses constant extra scalar state.

10

Exercises with worked solutions

Try before opening the solution. ★ applies an idea; ★★ combines ideas; ★★★ asks for design or proof.

Exercise 1 — Growth★

Classify 4n²+2n+9 tightly.

Worked solution

Θ(n²); the quadratic term dominates for large n.

Exercise 2 — Binary prerequisites★

Why not directly binary-search an unsorted catalogue?

Worked solution

The comparison no longer tells which half can be discarded; the ordering invariant is missing.

Exercise 3 — Nested loops★★

Count pairs visited by i in range(n), j in range(i).

Worked solution

0+1+…+(n−1)=n(n−1)/2, hence Θ(n²).

Exercise 4 — Halving★★

After four halvings of 64 candidates, how many remain?

Worked solution

Four remain. Six halvings reach one; precise probe counts depend on interval boundaries.

Exercise 5 — Stable ordering★★

Why preserve original order among equal titles?

Worked solution

It preserves a previously established secondary order, such as publication year. Stability is a contract property, not guaranteed by all sorts.

Exercise 6 — Amortise preprocessing★★★

Compare n=1000, one query versus 1000 queries after sorting.

Worked solution

One linear query costs at most 1000 checks; sorting costs on the order of 10000 comparisons. For many queries, sort once then use about logarithmic probes each, potentially saving work. Account for updates and actual constants.

Exercise 7 — Termination★★★

Why does [lo,hi) binary search finish?

Worked solution

When nonempty, mid is inside the interval. lo=mid+1 or hi=mid strictly shrinks its nonnegative integer length. It eventually reaches zero.

Exercise 8 — Space accounting★★

A function returns values.copy(); what is its output space?

Worked solution

Θ(n) references. Calling the algorithm in-place would be incorrect even if its auxiliary variables are constant-sized.

11

Self-check quiz

Choose an answer for feedback; reset to retry. A text answer key is available without JavaScript.

1

Θ(n) expresses?

2

Binary search requires?

3

Reverse insertion sort cost?

4

Stable sorting preserves?

5

Iterative binary search auxiliary space?

6

An average-case claim needs?

Answer key
  1. A — It describes asymptotic growth.
  2. B — Duplicates can be handled with boundary rules.
  3. C — Each key passes all preceding keys.
  4. A — Equal items keep relative order.
  5. B — It stores a few indices.
  6. C — Different distributions change averages.
12

Guided reading

  • MIT algorithms course — Use the sorting and binary-search materials; identify a precondition in each algorithm.
13

Review and the next step

Trace binary search on five items and justify every discarded interval. State insertion sort's invariant. Module 06 examines how the representation changes operation costs.

14

Key terms

TermMeaning
ComplexityResource growth as input size changes.
StabilityPreserving relative order of equal keys.
Auxiliary spaceWorking storage apart from input and designated output.