Analysis predicts a shape. Measure by counting operations as n grows. Wall-clock time in this tab is noisy (Pyodide). Step counts are the experiment.
Goal
Print scan vs nested-loop counts for n = 8, 16, 32.
Two algorithms
def scan_steps(n):
steps = 0
xs = list(range(n))
target = n - 1
for x in xs:
steps += 1
if x == target:
break
return steps
def pairs_steps(n):
steps = 0
for i in range(n):
for j in range(i + 1, n):
steps += 1
return steps
for n in (8, 16, 32):
s = scan_steps(n)
p = pairs_steps(n)
print(n, "scan", s, "pairs", p, "pairs/n2", round(p / (n * n), 3))Scan tracks n. Pairs track n(n-1)/2.
Sort comparisons (selection)
def selection_steps(n):
xs = list(range(n, 0, -1))
steps = 0
for i in range(n):
lo = i
for j in range(i + 1, n):
steps += 1
if xs[j] < xs[lo]:
lo = j
xs[i], xs[lo] = xs[lo], xs[i]
return steps
for n in (8, 16, 32):
print(n, "selection", selection_steps(n))About n²/2. That matches the nested loop, not n log n.
Tip
If the count does not match the Big-O story, the implementation is a different algorithm than you thought (or you counted the wrong thing).