Common Algorithms
Selection Sort
When memory writes are expensive, such as writing to flash storage or slow external devices, minimizing the number of swap operations becomes important. Selection sort addresses this by guaranteeing exactly n-1 swaps regardless of input, making it useful when write operations are costly.
Selection sort divides the list into sorted and unsorted portions. It repeatedly finds the minimum element from the unsorted portion and moves it to the end of the sorted portion.
Algorithm
- Find the minimum element in the unsorted portion
- Swap it with the first unsorted element
- Move the boundary between sorted and unsorted one position right
- Repeat until the entire list is sorted
find_minimum
Scan unsorted portion to locate the smallest element
Basic Implementation
basic.py
Replay: real traced execution (multi-file project)
# Basic selection sort
def selection_sort(arr):
"""Selection sort implementation"""
n = len(arr)
# Selection sort implementation
for i in range(n - 1):
# Find minimum in unsorted portion
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
# Swap minimum with first unsorted element
arr[i], arr[min_index] = arr[min_index], arr[i]
# Test selection sort
numbers = [64, 25, 12, 22, 11]
print("Before:", numbers)
selection_sort(numbers)
print("After: ", numbers)
# Basic selection sort
def selection_sort(arr):
"""Selection sort implementation"""
n = len(arr)
# Selection sort implementation
for i in range(n - 1):
# Find minimum in unsorted portion
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
# Swap minimum with first unsorted element
arr[i], arr[min_index] = arr[min_index], arr[i]
# Test selection sort
numbers = [29, 10, 14, 37, 13]
print("Before:", numbers)
selection_sort(numbers)
print("After: ", numbers)
# Basic selection sort
def selection_sort(arr):
"""Selection sort implementation"""
n = len(arr)
# Selection sort implementation
for i in range(n - 1):
# Find minimum in unsorted portion
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
# Swap minimum with first unsorted element
arr[i], arr[min_index] = arr[min_index], arr[i]
# Test selection sort
numbers = [4, 3, 2, 1]
print("Before:", numbers)
selection_sort(numbers)
print("After: ", numbers)
numbers ← [64, 25, 12, 22, 11]
20# Test selection sort21numbers→ [64, 25, 12, 22, 11] = [64, 25, 12, 22, 11]22#@numbers=[29, 10, 14, 37, 13], [4, 3, 2, 1]2324print("Before:", numbers[64, 25, 12, 22, 11])25selection_sort(numbers[64, 25, 12, 22, 11])26print("After: ", numbers)outputBefore: [64, 25, 12, 22, 11]n ← 5
4def selection_sort(arr[64, 25, 12, 22, 11]):5 """Selection sort implementation"""6 n→ 5 = len(arr[64, 25, 12, 22, 11])min_index ← 0
pass 1 of 48# Selection sort implementation9for i0 in range(n5 - 1):10 # Find minimum in unsorted portion11 min_index→ 0 = i012 for j in range(i + 1, n):All 4 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 4 3 3 for j in range(i + 1, n):
pass 1 of 1011min_index = i12for j1 in range(i0 + 1, n5):13 if arr[j] < arr[min_index]:14 min_index = jAll 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 min_index ← 1
pass 1 of 512for j in range(i + 1, n):13 if arr[j]25 < arr[min_index]64:14 min_index→ 1 = j1All 5 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 25 64 1 1 2 12 25 2 2 3 11 12 4 4 4 12 25 2 2 5 22 25 3 3 arr[i] ← 11, arr[min_index] ← 64
16# Swap minimum with first unsorted element17arr[i]→ 11, arr[min_index]→ 64 = arr[min_index], arr[i]arr[i] ← 12, arr[min_index] ← 25
16# Swap minimum with first unsorted element17arr[i]→ 12, arr[min_index]→ 25 = arr[min_index], arr[i]arr[i] ← 22, arr[min_index] ← 25
16# Swap minimum with first unsorted element17arr[i]→ 22, arr[min_index]→ 25 = arr[min_index], arr[i]arr[i] ← 25, arr[min_index] ← 25
16# Swap minimum with first unsorted element17arr[i]→ 25, arr[min_index]→ 25 = arr[min_index], arr[i]numbers ← [11, 12, 22, 25, 64]
24print("Before:", numbers)25selection_sort(numbers→ [11, 12, 22, 25, 64])26print("After: ", numbers[11, 12, 22, 25, 64])outputAfter: [11, 12, 22, 25, 64]
numbers ← [29, 10, 14, 37, 13]
20# Test selection sort21numbers→ [29, 10, 14, 37, 13] = [29, 10, 14, 37, 13]2223print("Before:", numbers[29, 10, 14, 37, 13])24selection_sort(numbers[29, 10, 14, 37, 13])25print("After: ", numbers)outputBefore: [29, 10, 14, 37, 13]n ← 5
4def selection_sort(arr[29, 10, 14, 37, 13]):5 """Selection sort implementation"""6 n→ 5 = len(arr[29, 10, 14, 37, 13])min_index ← 0
pass 1 of 48# Selection sort implementation9for i0 in range(n5 - 1):10 # Find minimum in unsorted portion11 min_index→ 0 = i012 for j in range(i + 1, n):All 4 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 4 3 3 for j in range(i + 1, n):
pass 1 of 1011min_index = i12for j1 in range(i0 + 1, n5):13 if arr[j] < arr[min_index]:14 min_index = jAll 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 min_index ← 1
pass 1 of 412for j in range(i + 1, n):13 if arr[j]10 < arr[min_index]29:14 min_index→ 1 = j1All 4 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 10 29 1 1 2 14 29 2 2 3 13 14 4 4 4 29 37 4 4 arr[i] ← 10, arr[min_index] ← 29
16# Swap minimum with first unsorted element17arr[i]→ 10, arr[min_index]→ 29 = arr[min_index], arr[i]arr[i] ← 13, arr[min_index] ← 29
16# Swap minimum with first unsorted element17arr[i]→ 13, arr[min_index]→ 29 = arr[min_index], arr[i]arr[i] ← 14, arr[min_index] ← 14
16# Swap minimum with first unsorted element17arr[i]→ 14, arr[min_index]→ 14 = arr[min_index], arr[i]arr[i] ← 29, arr[min_index] ← 37
16# Swap minimum with first unsorted element17arr[i]→ 29, arr[min_index]→ 37 = arr[min_index], arr[i]numbers ← [10, 13, 14, 29, 37]
23print("Before:", numbers)24selection_sort(numbers→ [10, 13, 14, 29, 37])25print("After: ", numbers[10, 13, 14, 29, 37])outputAfter: [10, 13, 14, 29, 37]
numbers ← [4, 3, 2, 1]
20# Test selection sort21numbers→ [4, 3, 2, 1] = [4, 3, 2, 1]2223print("Before:", numbers[4, 3, 2, 1])24selection_sort(numbers[4, 3, 2, 1])25print("After: ", numbers)outputBefore: [4, 3, 2, 1]n ← 4
4def selection_sort(arr[4, 3, 2, 1]):5 """Selection sort implementation"""6 n→ 4 = len(arr[4, 3, 2, 1])min_index ← 0
pass 1 of 38# Selection sort implementation9for i0 in range(n4 - 1):10 # Find minimum in unsorted portion11 min_index→ 0 = i012 for j in range(i + 1, n):All 3 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 for j in range(i + 1, n):
pass 1 of 611min_index = i12for j1 in range(i0 + 1, n4):13 if arr[j] < arr[min_index]:14 min_index = jAll 6 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 2 1 5 3 1 6 3 2 min_index ← 1
pass 1 of 412for j in range(i + 1, n):13 if arr[j]3 < arr[min_index]4:14 min_index→ 1 = j1All 4 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 3 4 1 1 2 2 3 2 2 3 1 2 3 3 4 2 3 2 2 arr[i] ← 1, arr[min_index] ← 4
16# Swap minimum with first unsorted element17arr[i]→ 1, arr[min_index]→ 4 = arr[min_index], arr[i]arr[i] ← 2, arr[min_index] ← 3
16# Swap minimum with first unsorted element17arr[i]→ 2, arr[min_index]→ 3 = arr[min_index], arr[i]arr[i] ← 3, arr[min_index] ← 3
16# Swap minimum with first unsorted element17arr[i]→ 3, arr[min_index]→ 3 = arr[min_index], arr[i]numbers ← [1, 2, 3, 4]
23print("Before:", numbers)24selection_sort(numbers→ [1, 2, 3, 4])25print("After: ", numbers[1, 2, 3, 4])outputAfter: [1, 2, 3, 4]
Trace Example
trace.py
Replay: real traced execution (multi-file project)
# Selection sort with trace
def selection_sort_trace(arr):
"""Selection sort with step-by-step trace"""
n = len(arr)
# Trace each pass
for i in range(n - 1):
print(f"Pass {i + 1}:")
# Find minimum
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
print(f" Min in unsorted portion: {arr[min_index]} at index {min_index}")
# Swap
if min_index != i:
print(f" Swap positions {i} and {min_index}")
arr[i], arr[min_index] = arr[min_index], arr[i]
else:
print(" Already in position")
print(f" Result: {arr}")
# Test with trace
numbers = [5, 2, 8, 1, 9]
print("Initial:", numbers)
print()
selection_sort_trace(numbers)
numbers ← [5, 2, 8, 1, 9]
30# Test with trace31numbers→ [5, 2, 8, 1, 9] = [5, 2, 8, 1, 9]3233print("Initial:", numbers[5, 2, 8, 1, 9])34print()35selection_sort_trace(numbers[5, 2, 8, 1, 9])outputInitial: [5, 2, 8, 1, 9]n ← 5
4def selection_sort_trace(arr[5, 2, 8, 1, 9]):5 """Selection sort with step-by-step trace"""6 n→ 5 = len(arr[5, 2, 8, 1, 9])min_index ← 0
pass 1 of 48# Trace each pass9for i0 in range(n5 - 1):10 print(f"Pass {i0 + 1}:")1112 # Find minimum13 min_index→ 0 = i014 for j in range(i + 1, n):outputPass 1:All 4 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 4 3 3 for j in range(i + 1, n):
pass 1 of 1013min_index = i14for j1 in range(i0 + 1, n5):15 if arr[j] < arr[min_index]:16 min_index = jAll 10 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 2 1 6 3 1 7 4 1 8 3 2 9 4 2 10 4 3 min_index ← 1
pass 1 of 314for j in range(i + 1, n):15 if arr[j]2 < arr[min_index]5:16 min_index→ 1 = j1All 3 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 2 5 1 1 2 1 2 3 3 3 5 8 3 3 print(f" Min in unsorted portion: {arr[min_index]} at index {min_inde…
18print(f" Min in unsorted portion: {arr[min_index]1} at index {min_index3}")output Min in unsorted portion: 1 at index 3arr[i] ← 1, arr[min_index] ← 5
pass 1 of 220# Swap21if min_index3 != i0:22 print(f" Swap positions {i0} and {min_index3}")23 arr[i]→ 1, arr[min_index]→ 5 = arr[min_index], arr[i]24else:output Swap positions 0 and 3print(f" Result: {arr}")
27print(f" Result: {arr[1, 2, 8, 5, 9]}")output Result: [1, 2, 8, 5, 9]print(f" Min in unsorted portion: {arr[min_index]} at index {min_inde…
18print(f" Min in unsorted portion: {arr[min_index]2} at index {min_index1}")output Min in unsorted portion: 2 at index 1else:
pass 1 of 222 print(f" Swap positions {i} and {min_index}")23 arr[i], arr[min_index] = arr[min_index], arr[i]24else:25 print(" Already in position")output Already in positionprint(f" Result: {arr}")
27print(f" Result: {arr[1, 2, 8, 5, 9]}")output Result: [1, 2, 8, 5, 9]print(f" Min in unsorted portion: {arr[min_index]} at index {min_inde…
18print(f" Min in unsorted portion: {arr[min_index]5} at index {min_index3}")output Min in unsorted portion: 5 at index 3arr[i] ← 5, arr[min_index] ← 8
pass 2 of 220# Swap21if min_index3 != i2:22 print(f" Swap positions {i2} and {min_index3}")23 arr[i]→ 5, arr[min_index]→ 8 = arr[min_index], arr[i]24else:output Swap positions 2 and 3print(f" Result: {arr}")
27print(f" Result: {arr[1, 2, 5, 8, 9]}")output Result: [1, 2, 5, 8, 9]print(f" Min in unsorted portion: {arr[min_index]} at index {min_inde…
18print(f" Min in unsorted portion: {arr[min_index]8} at index {min_index3}")output Min in unsorted portion: 8 at index 3else:
pass 2 of 222 print(f" Swap positions {i} and {min_index}")23 arr[i], arr[min_index] = arr[min_index], arr[i]24else:25 print(" Already in position")output Already in positionprint(f" Result: {arr}")
27print(f" Result: {arr[1, 2, 5, 8, 9]}")output Result: [1, 2, 5, 8, 9]numbers ← [1, 2, 5, 8, 9]
34print()35selection_sort_trace(numbers→ [1, 2, 5, 8, 9])
Finding Maximum (Descending Sort)
find_max.py
Replay: real traced execution (multi-file project)
# Find maximum variant
def selection_sort_max(arr):
"""Selection sort finding maximum"""
n = len(arr)
# Selection sort finding maximum
for i in range(n - 1, 0, -1):
# Find maximum in unsorted portion
max_index = 0
for j in range(1, i + 1):
if arr[j] > arr[max_index]:
max_index = j
# Swap maximum with last unsorted element
arr[i], arr[max_index] = arr[max_index], arr[i]
# Test maximum variant
numbers = [64, 25, 12, 22, 11]
print("Before:", numbers)
selection_sort_max(numbers)
print("After: ", numbers)
numbers ← [64, 25, 12, 22, 11]
20# Test maximum variant21numbers→ [64, 25, 12, 22, 11] = [64, 25, 12, 22, 11]2223print("Before:", numbers[64, 25, 12, 22, 11])24selection_sort_max(numbers[64, 25, 12, 22, 11])25print("After: ", numbers)outputBefore: [64, 25, 12, 22, 11]n ← 5
4def selection_sort_max(arr[64, 25, 12, 22, 11]):5 """Selection sort finding maximum"""6 n→ 5 = len(arr[64, 25, 12, 22, 11])max_index ← 0
pass 1 of 48# Selection sort finding maximum9for i4 in range(n5 - 1, 0, -1):10 # Find maximum in unsorted portion11 max_index→ 0 = 012 for j in range(1, i + 1):All 4 passes — pass 1 is the card above pass imax_index1 4 0 2 3 0 3 2 0 4 1 0 for j in range(1, i + 1):
pass 1 of 1011max_index = 012for j1 in range(1, i4 + 1):13 if arr[j] > arr[max_index]:14 max_index = jAll 10 passes — pass 1 is the card above pass ji1 1 4 2 2 4 3 3 4 4 4 4 5 1 3 6 2 3 7 3 3 8 1 2 9 2 2 10 1 1 arr[i] ← 64, arr[max_index] ← 11
16# Swap maximum with last unsorted element17arr[i]→ 64, arr[max_index]→ 11 = arr[max_index], arr[i]max_index ← 1
pass 1 of 312for j in range(1, i + 1):13 if arr[j]25 > arr[max_index]11:14 max_index→ 1 = j1All 3 passes — pass 1 is the card above pass arr[j]max_index1 25 1 2 22 1 3 12 1 arr[i] ← 25, arr[max_index] ← 22
16# Swap maximum with last unsorted element17arr[i]→ 25, arr[max_index]→ 22 = arr[max_index], arr[i]arr[i] ← 22, arr[max_index] ← 12
16# Swap maximum with last unsorted element17arr[i]→ 22, arr[max_index]→ 12 = arr[max_index], arr[i]arr[i] ← 12, arr[max_index] ← 12
16# Swap maximum with last unsorted element17arr[i]→ 12, arr[max_index]→ 12 = arr[max_index], arr[i]numbers ← [11, 12, 22, 25, 64]
23print("Before:", numbers)24selection_sort_max(numbers→ [11, 12, 22, 25, 64])25print("After: ", numbers[11, 12, 22, 25, 64])outputAfter: [11, 12, 22, 25, 64]
Counting Operations
count.py
Replay: real traced execution (multi-file project)
# Count comparisons and swaps
def selection_sort_counted(arr):
"""Selection sort that counts operations"""
n = len(arr)
comparisons = 0
swaps = 0
# Count operations
for i in range(n - 1):
min_index = i
for j in range(i + 1, n):
comparisons += 1
if arr[j] < arr[min_index]:
min_index = j
if min_index != i:
swaps += 1
arr[i], arr[min_index] = arr[min_index], arr[i]
return comparisons, swaps
# Test on different inputs
sorted_list = [1, 2, 3, 4, 5]
reversed_list = [5, 4, 3, 2, 1]
random_list = [3, 1, 4, 2, 5]
comp1, swap1 = selection_sort_counted(sorted_list.copy())
print(f"Already sorted: {comp1} comparisons, {swap1} swaps")
comp2, swap2 = selection_sort_counted(reversed_list.copy())
print(f"Reverse sorted: {comp2} comparisons, {swap2} swaps")
comp3, swap3 = selection_sort_counted(random_list.copy())
print(f"Random order: {comp3} comparisons, {swap3} swaps")
sorted_list ← [1, 2, 3, 4, 5], reversed_list ← [5, 4, 3, 2, 1]
26# Test on different inputs27sorted_list→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]28reversed_list→ [5, 4, 3, 2, 1] = [5, 4, 3, 2, 1]29random_list→ [3, 1, 4, 2, 5] = [3, 1, 4, 2, 5]3031comp1, swap1 = selection_sort_counted(sorted_list[1, 2, 3, 4, 5].copy())32print(f"Already sorted: {comp1} comparisons, {swap1} swaps")n ← 5, comparisons ← 0, swaps ← 0
pass 1 of 34def selection_sort_counted(arr[1, 2, 3, 4, 5]):5 """Selection sort that counts operations"""6 n→ 5 = len(arr[1, 2, 3, 4, 5])7 comparisons→ 0 = 08 swaps→ 0 = 0All 3 passes — pass 1 is the card above pass arrncomparisonsswaps1 [1, 2, 3, 4, 5] 5 0 0 2 [5, 4, 3, 2, 1] 5 0 0 3 [3, 1, 4, 2, 5] 5 0 0 min_index ← 0
pass 1 of 1210# Count operations11for i0 in range(n5 - 1):12 min_index→ 0 = i0All 12 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 4 3 3 5 0 0 6 1 1 7 2 2 8 3 3 9 0 0 10 1 1 11 2 2 12 3 3 comparisons ← 1
pass 1 of 3014for j1 in range(i0 + 1, n5):15 comparisons→ 1 += 116 if arr[j] < arr[min_index]:30 passes — pass 1 is the card above pass jicomparisons1 1 0 0 → 1 2 2 0 1 → 2 3 3 0 2 → 3 4 4 0 3 → 4 5 2 1 4 → 5 6 3 1 5 → 6 7 4 1 6 → 7 8 3 2 7 → 8 9 4 2 8 → 9 ⋯ 19 more passes ⋯ 29 4 2 8 → 9 30 4 3 9 → 10 return comparisons, swaps
23return comparisons10, swaps0comp1 ← 10, swap1 ← 0
31comp1→ 10, swap1→ 0 = selection_sort_counted(sorted_list[1, 2, 3, 4, 5].copy())32print(f"Already sorted: {comp110} comparisons, {swap10} swaps")3334comp2, swap2 = selection_sort_counted(reversed_list[5, 4, 3, 2, 1].copy())35print(f"Reverse sorted: {comp2} comparisons, {swap2} swaps")outputAlready sorted: 10 comparisons, 0 swapsmin_index ← 1
pass 1 of 915comparisons += 116if arr[j]4 < arr[min_index]5:17 min_index→ 1 = j1All 9 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 4 5 1 1 2 3 4 2 2 3 2 3 3 3 4 1 2 4 4 5 3 4 2 2 6 2 3 3 3 7 1 3 1 1 8 2 3 3 3 9 3 4 3 3 swaps ← 1, arr[i] ← 1, arr[min_index] ← 5
pass 1 of 519if min_index4 != i0:20 swaps→ 1 += 121 arr[i]→ 1, arr[min_index]→ 5 = arr[min_index], arr[i]All 5 passes — pass 1 is the card above pass min_indexiswapsarr[i]arr[min_index]1 4 0 0 → 1 5 → 1 1 → 5 2 3 1 1 → 2 4 → 2 2 → 4 3 1 0 0 → 1 3 → 1 1 → 3 4 3 1 1 → 2 3 → 2 2 → 3 5 3 2 2 → 3 4 → 3 3 → 4 return comparisons, swaps
23return comparisons10, swaps2comp2 ← 10, swap2 ← 2
34comp2→ 10, swap2→ 2 = selection_sort_counted(reversed_list[5, 4, 3, 2, 1].copy())35print(f"Reverse sorted: {comp210} comparisons, {swap22} swaps")3637comp3, swap3 = selection_sort_counted(random_list[3, 1, 4, 2, 5].copy())38print(f"Random order: {comp3} comparisons, {swap3} swaps")outputReverse sorted: 10 comparisons, 2 swapsreturn comparisons, swaps
23return comparisons10, swaps3comp3 ← 10, swap3 ← 3
37comp3→ 10, swap3→ 3 = selection_sort_counted(random_list[3, 1, 4, 2, 5].copy())38print(f"Random order: {comp310} comparisons, {swap33} swaps")outputRandom order: 10 comparisons, 3 swaps
Comparison with Bubble Sort
compare.py
Replay: real traced execution (multi-file project)
# Compare with bubble sort
def bubble_sort_swaps(arr):
"""Bubble sort counting swaps"""
n = len(arr)
swaps = 0
for i in range(n - 1):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
swaps += 1
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return swaps
def selection_sort_swaps(arr):
"""Selection sort counting swaps"""
n = len(arr)
swaps = 0
for i in range(n - 1):
min_index = i
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
if min_index != i:
swaps += 1
arr[i], arr[min_index] = arr[min_index], arr[i]
return swaps
# Compare swap counts
reversed_list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
bubble_swaps = bubble_sort_swaps(reversed_list.copy())
print(f"Bubble sort swaps: {bubble_swaps}")
selection_swaps = selection_sort_swaps(reversed_list.copy())
print(f"Selection sort swaps: {selection_swaps}")
print("\nSelection sort makes fewer swaps!")
reversed_list ← [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
36# Compare swap counts37reversed_list→ [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]3839bubble_swaps = bubble_sort_swaps(reversed_list[10, 9, 8, 7, 6, 5, 4, 3, 2, 1].copy())40print(f"Bubble sort swaps: {bubble_swaps}")n ← 10, swaps ← 0
4def bubble_sort_swaps(arr[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]):5 """Bubble sort counting swaps"""6 n→ 10 = len(arr[10, 9, 8, 7, 6, 5, 4, 3, 2, 1])7 swaps→ 0 = 0for i in range(n - 1):
pass 1 of 99for i0 in range(n10 - 1):10 for j in range(n - i - 1):11 if arr[j] > arr[j + 1]:All 9 passes — pass 1 is the card above pass i1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 for j in range(n - i - 1):
pass 1 of 459for i in range(n - 1):10 for j0 in range(n10 - i0 - 1):11 if arr[j] > arr[j + 1]:12 swaps += 145 passes — pass 1 is the card above pass ji1 0 0 2 1 0 3 2 0 4 3 0 5 4 0 6 5 0 7 6 0 8 7 0 9 8 0 ⋯ 34 more passes ⋯ 44 1 7 45 0 8 swaps ← 1, arr[j] ← 9, arr[j + 1] ← 10
pass 1 of 4510for j in range(n - i - 1):11 if arr[j]10 > arr[j + 1]9:12 swaps→ 1 += 113 arr[j]→ 9, arr[j + 1]→ 10 = arr[j + 1], arr[j]45 passes — pass 1 is the card above pass swapsarr[j]arr[j + 1]1 0 → 1 10 → 9 9 → 10 2 1 → 2 10 → 8 8 → 10 3 2 → 3 10 → 7 7 → 10 4 3 → 4 10 → 6 6 → 10 5 4 → 5 10 → 5 5 → 10 6 5 → 6 10 → 4 4 → 10 7 6 → 7 10 → 3 3 → 10 8 7 → 8 10 → 2 2 → 10 9 8 → 9 10 → 1 1 → 10 ⋯ 34 more passes ⋯ 44 43 → 44 3 → 1 1 → 3 45 44 → 45 2 → 1 1 → 2 return swaps
15return swaps45bubble_swaps ← 45
39bubble_swaps→ 45 = bubble_sort_swaps(reversed_list[10, 9, 8, 7, 6, 5, 4, 3, 2, 1].copy())40print(f"Bubble sort swaps: {bubble_swaps45}")4142selection_swaps = selection_sort_swaps(reversed_list[10, 9, 8, 7, 6, 5, 4, 3, 2, 1].copy())43print(f"Selection sort swaps: {selection_swaps}")outputBubble sort swaps: 45n ← 10, swaps ← 0
18def selection_sort_swaps(arr[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]):19 """Selection sort counting swaps"""20 n→ 10 = len(arr[10, 9, 8, 7, 6, 5, 4, 3, 2, 1])21 swaps→ 0 = 0min_index ← 0
pass 1 of 923for i0 in range(n10 - 1):24 min_index→ 0 = i025 for j in range(i + 1, n):All 9 passes — pass 1 is the card above pass imin_index1 0 0 2 1 1 3 2 2 4 3 3 5 4 4 6 5 5 7 6 6 8 7 7 9 8 8 for j in range(i + 1, n):
pass 1 of 4524min_index = i25for j1 in range(i0 + 1, n10):26 if arr[j] < arr[min_index]:27 min_index = j45 passes — pass 1 is the card above pass ji1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 7 7 0 8 8 0 9 9 0 ⋯ 34 more passes ⋯ 44 9 7 45 9 8 min_index ← 1
pass 1 of 2525for j in range(i + 1, n):26 if arr[j]9 < arr[min_index]10:27 min_index→ 1 = j125 passes — pass 1 is the card above pass arr[j]arr[min_index]jmin_index1 9 10 1 1 2 8 9 2 2 3 7 8 3 3 4 6 7 4 4 5 5 6 5 5 6 4 5 6 6 7 3 4 7 7 8 2 3 8 8 9 1 2 9 9 ⋯ 14 more passes ⋯ 24 4 5 6 6 25 5 6 5 5 swaps ← 1, arr[i] ← 1, arr[min_index] ← 10
pass 1 of 529if min_index9 != i0:30 swaps→ 1 += 131 arr[i]→ 1, arr[min_index]→ 10 = arr[min_index], arr[i]All 5 passes — pass 1 is the card above pass min_indexiswapsarr[i]arr[min_index]1 9 0 0 → 1 10 → 1 1 → 10 2 8 1 1 → 2 9 → 2 2 → 9 3 7 2 2 → 3 8 → 3 3 → 8 4 6 3 3 → 4 7 → 4 4 → 7 5 5 4 4 → 5 6 → 5 5 → 6 return swaps
33return swaps5selection_swaps ← 5
42selection_swaps→ 5 = selection_sort_swaps(reversed_list[10, 9, 8, 7, 6, 5, 4, 3, 2, 1].copy())43print(f"Selection sort swaps: {selection_swaps5}")4445print("\nSelection sort makes fewer swaps!")outputSelection sort swaps: 5 Selection sort makes fewer swaps!
minimal_swaps
Selection sort performs exactly n-1 swaps, regardless of input order
Characteristics
- Time complexity: O(n^2) - two nested loops
- Space complexity: O(1) - sorts in place
- Unstable: equal elements may change relative order
- Best case: O(n^2) - always scans entire unsorted portion
- Worst case: O(n^2) - same as best case
- Fewer swaps: only n-1 swaps
Exercise: practical.py
Implement selection sort to arrange a playlist by song duration, tracking and displaying the number of swaps performed