import random
def selection_sort(a):
comps = moves = 0
n = len(a)
for p in range(n - 1):
smallest = p
for i in range(p + 1, n):
comps += 1
if a[i] < a[smallest]:
smallest = i
if smallest != p:
a[p], a[smallest] = a[smallest], a[p]
moves += 1 # one swap
return comps, moves
def bubble_sort(a):
comps = moves = 0
n = len(a)
for p in range(n - 1):
swapped = False
for i in range(n - 1 - p):
comps += 1
if a[i] > a[i + 1]:
a[i], a[i + 1] = a[i + 1], a[i]
moves += 1
swapped = True
if not swapped: # early exit: already sorted
break
return comps, moves
def insertion_sort(a):
comps = moves = 0
for i in range(1, len(a)):
key = a[i]
j = i - 1
while j >= 0:
comps += 1
if a[j] > key:
a[j + 1] = a[j]
moves += 1 # one shift
j -= 1
else:
break
a[j + 1] = key
return comps, moves
random.seed(2026)
n = 400
shuffled = list(range(n))
random.shuffle(shuffled)
inputs = {"sorted": list(range(n)), "random": shuffled, "reversed": list(range(n, 0, -1))}
for sort in (selection_sort, bubble_sort, insertion_sort):
for name, data in inputs.items():
comps, moves = sort(data[:]) # sort a copy
print(f"{sort.__name__:15}{name:9}{comps:7}{moves:7}")
Its checked output is shown in the next box. Columns: algorithm, input, comparisons, moves. random.seed(2026) makes the shuffle the same every time you run it, so you should see these exact numbers.