Organizing data in order is fundamental to computing, from displaying search results to preparing data for efficient lookup. Bubble sort is one of the simplest sorting algorithms to understand and implement, making it an excellent starting point for learning how sorting works, even though faster algorithms exist for production use.

Bubble sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. Larger elements "bubble up" to the end.

Algorithm

  1. Repeat for each element:
    • Compare adjacent pairs
    • If out of order, swap them
  2. After each pass, the largest unsorted element is in its final position
  3. Repeat until no swaps are made
adjacent_swap Compare neighboring elements and swap if out of order

Basic Implementation

numbers
basic.py
Replay: real traced execution (multi-file project)
# Basic bubble sort


def bubble_sort(arr):
    """Bubble sort implementation"""
    n = len(arr)

    # Bubble sort implementation
    for i in range(n - 1):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                # Swap
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


# Test bubble sort
numbers = [64, 34, 25, 12, 22, 11, 90]

print("Before:", numbers)
bubble_sort(numbers)
print("After: ", numbers)

# Basic bubble sort


def bubble_sort(arr):
    """Bubble sort implementation"""
    n = len(arr)

    # Bubble sort implementation
    for i in range(n - 1):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                # Swap
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


# Test bubble sort
numbers = [5, 1, 4, 2, 8]

print("Before:", numbers)
bubble_sort(numbers)
print("After: ", numbers)

# Basic bubble sort


def bubble_sort(arr):
    """Bubble sort implementation"""
    n = len(arr)

    # Bubble sort implementation
    for i in range(n - 1):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                # Swap
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


# Test bubble sort
numbers = [3, 2, 1]

print("Before:", numbers)
bubble_sort(numbers)
print("After: ", numbers)

  1. numbers ← [64, 34, 25, 12, 22, 11, 90]

    16# Test bubble sort17numbers→ [64, 34, 25, 12, 22, 11, 90] = [64, 34, 25, 12, 22, 11, 90]18#@numbers=[5, 1, 4, 2, 8], [3, 2, 1]1920print("Before:", numbers[64, 34, 25, 12, 22, 11, 90])21bubble_sort(numbers[64, 34, 25, 12, 22, 11, 90])22print("After: ", numbers)
    outputBefore: [64, 34, 25, 12, 22, 11, 90]
  2. n ← 7

    4def bubble_sort(arr[64, 34, 25, 12, 22, 11, 90]):5    """Bubble sort implementation"""6    n→ 7 = len(arr[64, 34, 25, 12, 22, 11, 90])
  3. for i in range(n - 1):

    pass 1 of 6
    8# Bubble sort implementation9for i0 in range(n7 - 1):10    for j in range(n - i - 1):11        if arr[j] > arr[j + 1]:
    All 6 passes — pass 1 is the card above
    passi
    10
    21
    32
    43
    54
    65
  4. for j in range(n - i - 1):

    pass 1 of 21
    9for i in range(n - 1):10    for j0 in range(n7 - i0 - 1):11        if arr[j] > arr[j + 1]:12            # Swap
    21 passes — pass 1 is the card above
    passji
    100
    210
    320
    430
    540
    650
    701
    811
    921
    ⋯ 10 more passes ⋯
    2014
    2105
  5. arr[j] ← 34, arr[j + 1] ← 64

    pass 1 of 14
    10for j in range(n - i - 1):11    if arr[j]64 > arr[j + 1]34:12        # Swap13        arr[j]→ 34, arr[j + 1]→ 64 = arr[j + 1], arr[j]
    14 passes — pass 1 is the card above
    passarr[j]arr[j + 1]
    164 → 3434 → 64
    264 → 2525 → 64
    364 → 1212 → 64
    464 → 2222 → 64
    564 → 1111 → 64
    634 → 2525 → 34
    734 → 1212 → 34
    834 → 2222 → 34
    934 → 1111 → 34
    ⋯ 3 more passes ⋯
    1322 → 1111 → 22
    1412 → 1111 → 12
  6. numbers ← [11, 12, 22, 25, 34, 64, 90]

    20print("Before:", numbers)21bubble_sort(numbers→ [11, 12, 22, 25, 34, 64, 90])22print("After: ", numbers[11, 12, 22, 25, 34, 64, 90])
    outputAfter:  [11, 12, 22, 25, 34, 64, 90]
  1. numbers ← [5, 1, 4, 2, 8]

    16# Test bubble sort17numbers→ [5, 1, 4, 2, 8] = [5, 1, 4, 2, 8]1819print("Before:", numbers[5, 1, 4, 2, 8])20bubble_sort(numbers[5, 1, 4, 2, 8])21print("After: ", numbers)
    outputBefore: [5, 1, 4, 2, 8]
  2. n ← 5

    4def bubble_sort(arr[5, 1, 4, 2, 8]):5    """Bubble sort implementation"""6    n→ 5 = len(arr[5, 1, 4, 2, 8])
  3. for i in range(n - 1):

    pass 1 of 4
    8# Bubble sort implementation9for i0 in range(n5 - 1):10    for j in range(n - i - 1):11        if arr[j] > arr[j + 1]:
    All 4 passes — pass 1 is the card above
    passi
    10
    21
    32
    43
  4. for j in range(n - i - 1):

    pass 1 of 10
    9for i in range(n - 1):10    for j0 in range(n5 - i0 - 1):11        if arr[j] > arr[j + 1]:12            # Swap
    All 10 passes — pass 1 is the card above
    passji
    100
    210
    320
    430
    501
    611
    721
    802
    912
    1003
  5. arr[j] ← 1, arr[j + 1] ← 5

    pass 1 of 4
    10for j in range(n - i - 1):11    if arr[j]5 > arr[j + 1]1:12        # Swap13        arr[j]→ 1, arr[j + 1]→ 5 = arr[j + 1], arr[j]
    All 4 passes — pass 1 is the card above
    passarr[j]arr[j + 1]
    15 → 11 → 5
    25 → 44 → 5
    35 → 22 → 5
    44 → 22 → 4
  6. numbers ← [1, 2, 4, 5, 8]

    19print("Before:", numbers)20bubble_sort(numbers→ [1, 2, 4, 5, 8])21print("After: ", numbers[1, 2, 4, 5, 8])
    outputAfter:  [1, 2, 4, 5, 8]
  1. numbers ← [3, 2, 1]

    16# Test bubble sort17numbers→ [3, 2, 1] = [3, 2, 1]1819print("Before:", numbers[3, 2, 1])20bubble_sort(numbers[3, 2, 1])21print("After: ", numbers)
    outputBefore: [3, 2, 1]
  2. n ← 3

    4def bubble_sort(arr[3, 2, 1]):5    """Bubble sort implementation"""6    n→ 3 = len(arr[3, 2, 1])
  3. for i in range(n - 1):

    pass 1 of 2
    8# Bubble sort implementation9for i0 in range(n3 - 1):10    for j in range(n - i - 1):11        if arr[j] > arr[j + 1]:
  4. for j in range(n - i - 1):

    pass 1 of 3
    9for i in range(n - 1):10    for j0 in range(n3 - i0 - 1):11        if arr[j] > arr[j + 1]:12            # Swap
    All 3 passes — pass 1 is the card above
    passji
    100
    210
    301
  5. arr[j] ← 2, arr[j + 1] ← 3

    pass 1 of 3
    10for j in range(n - i - 1):11    if arr[j]3 > arr[j + 1]2:12        # Swap13        arr[j]→ 2, arr[j + 1]→ 3 = arr[j + 1], arr[j]
    All 3 passes — pass 1 is the card above
    passinarr[j]arr[j + 1]
    1——3 → 22 → 3
    2133 → 11 → 3
    3——2 → 11 → 2
  6. for i in range(n - 1):

    pass 2 of 2
    8# Bubble sort implementation9for i1 in range(n3 - 1):10    for j in range(n - i - 1):11        if arr[j] > arr[j + 1]:
  7. numbers ← [1, 2, 3]

    19print("Before:", numbers)20bubble_sort(numbers→ [1, 2, 3])21print("After: ", numbers[1, 2, 3])
    outputAfter:  [1, 2, 3]

Trace Example

trace.py
Replay: real traced execution (multi-file project)
# Bubble sort with trace


def bubble_sort_trace(arr):
    """Bubble sort with step-by-step trace"""
    n = len(arr)

    # Trace each pass
    for i in range(n - 1):
        print(f"Pass {i + 1}:")
        swapped = False

        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                print(f"  Swap {arr[j]} and {arr[j + 1]}")
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True

        print(f"  Result: {arr}")

        if not swapped:
            print("  No swaps - array is sorted!")
            break


# Test with trace
numbers = [5, 2, 8, 1, 9]

print("Initial:", numbers)
print()
bubble_sort_trace(numbers)

  1. numbers ← [5, 2, 8, 1, 9]

    26# Test with trace27numbers→ [5, 2, 8, 1, 9] = [5, 2, 8, 1, 9]2829print("Initial:", numbers[5, 2, 8, 1, 9])30print()31bubble_sort_trace(numbers[5, 2, 8, 1, 9])
    outputInitial: [5, 2, 8, 1, 9]
  2. n ← 5

    4def bubble_sort_trace(arr[5, 2, 8, 1, 9]):5    """Bubble sort with step-by-step trace"""6    n→ 5 = len(arr[5, 2, 8, 1, 9])
  3. swapped ← False

    pass 1 of 4
    8# Trace each pass9for i0 in range(n5 - 1):10    print(f"Pass {i0 + 1}:")11    swapped→ False = False
    outputPass 1:
    All 4 passes — pass 1 is the card above
    passiswapped
    10False
    21False
    32False
    43False
  4. for j in range(n - i - 1):

    pass 1 of 10
    13for j0 in range(n5 - i0 - 1):14    if arr[j] > arr[j + 1]:15        print(f"  Swap {arr[j]} and {arr[j + 1]}")
    All 10 passes — pass 1 is the card above
    passji
    100
    210
    320
    430
    501
    611
    721
    802
    912
    1003
  5. arr[j] ← 2, arr[j + 1] ← 5, swapped ← True

    pass 1 of 4
    13for j in range(n - i - 1):14    if arr[j]5 > arr[j + 1]2:15        print(f"  Swap {arr[j]5} and {arr[j + 1]2}")16        arr[j]→ 2, arr[j + 1]→ 5 = arr[j + 1], arr[j]17        swapped→ True = True
    output  Swap 5 and 2
    All 4 passes — pass 1 is the card above
    passarr[j]arr[j + 1]swapped
    15 → 22 → 5True
    28 → 11 → 8True
    35 → 11 → 5True
    42 → 11 → 2True
  6. print(f" Result: {arr}")

    19print(f"  Result: {arr[2, 5, 1, 8, 9]}")
    output  Result: [2, 5, 1, 8, 9]
  7. print(f" Result: {arr}")

    19print(f"  Result: {arr[2, 1, 5, 8, 9]}")
    output  Result: [2, 1, 5, 8, 9]
  8. print(f" Result: {arr}")

    19print(f"  Result: {arr[1, 2, 5, 8, 9]}")
    output  Result: [1, 2, 5, 8, 9]
  9. print(f" Result: {arr}")

    19print(f"  Result: {arr[1, 2, 5, 8, 9]}")
    output  Result: [1, 2, 5, 8, 9]
  10. if not swapped:

    21if not swappedFalse:22    print("  No swaps - array is sorted!")23    break
    output  No swaps - array is sorted!
  11. numbers ← [1, 2, 5, 8, 9]

    30print()31bubble_sort_trace(numbers→ [1, 2, 5, 8, 9])

Optimized Version

optimized.py
Replay: real traced execution (multi-file project)
# Optimized bubble sort


def bubble_sort_optimized(arr):
    """Optimized bubble sort with early termination"""
    n = len(arr)
    passes = 0

    # Optimized with early termination
    for i in range(n - 1):
        passes += 1
        swapped = False

        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True

        # If no swaps, array is sorted
        if not swapped:
            break

    return passes


# Test on different inputs
almost_sorted = [1, 2, 3, 5, 4, 6, 7, 8]
reversed_list = [8, 7, 6, 5, 4, 3, 2, 1]

print("Almost sorted:")
print("Before:", almost_sorted)
passes1 = bubble_sort_optimized(almost_sorted)
print("After: ", almost_sorted)
print("Passes:", passes1)

print("\nReverse sorted:")
print("Before:", reversed_list)
passes2 = bubble_sort_optimized(reversed_list)
print("After: ", reversed_list)
print("Passes:", passes2)

  1. almost_sorted ← [1, 2, 3, 5, 4, 6, 7, 8], reversed_list ← [8, 7, 6, 5, 4, 3, 2, 1]

    26# Test on different inputs27almost_sorted→ [1, 2, 3, 5, 4, 6, 7, 8] = [1, 2, 3, 5, 4, 6, 7, 8]28reversed_list→ [8, 7, 6, 5, 4, 3, 2, 1] = [8, 7, 6, 5, 4, 3, 2, 1]2930print("Almost sorted:")31print("Before:", almost_sorted[1, 2, 3, 5, 4, 6, 7, 8])32passes1 = bubble_sort_optimized(almost_sorted[1, 2, 3, 5, 4, 6, 7, 8])33print("After: ", almost_sorted)
    outputAlmost sorted:
    Before: [1, 2, 3, 5, 4, 6, 7, 8]
  2. n ← 8, passes ← 0

    pass 1 of 2
    4def bubble_sort_optimized(arr[1, 2, 3, 5, 4, 6, 7, 8]):5    """Optimized bubble sort with early termination"""6    n→ 8 = len(arr[1, 2, 3, 5, 4, 6, 7, 8])7    passes→ 0 = 0
  3. passes ← 1, swapped ← False

    pass 1 of 9
    9# Optimized with early termination10for i0 in range(n8 - 1):11    passes→ 1 += 112    swapped→ False = False
    All 9 passes — pass 1 is the card above
    passipassesswapped
    100 → 1False
    211 → 2False
    300 → 1False
    411 → 2False
    522 → 3False
    633 → 4False
    744 → 5False
    855 → 6False
    966 → 7False
  4. for j in range(n - i - 1):

    pass 1 of 41
    14for j0 in range(n8 - i0 - 1):15    if arr[j] > arr[j + 1]:16        arr[j], arr[j + 1] = arr[j + 1], arr[j]
    41 passes — pass 1 is the card above
    passjiswapped
    100—
    210—
    320—
    430—
    540—
    650—
    760—
    801—
    911—
    ⋯ 30 more passes ⋯
    4015—
    4106—
  5. arr[j] ← 4, arr[j + 1] ← 5, swapped ← True

    pass 1 of 29
    14for j in range(n - i - 1):15    if arr[j]5 > arr[j + 1]4:16        arr[j]→ 4, arr[j + 1]→ 5 = arr[j + 1], arr[j]17        swapped→ True = True
    29 passes — pass 1 is the card above
    passarr[j]arr[j + 1]swapped
    15 → 44 → 5True
    28 → 77 → 8True
    38 → 66 → 8True
    48 → 55 → 8True
    58 → 44 → 8True
    68 → 33 → 8True
    78 → 22 → 8True
    88 → 11 → 8True
    97 → 66 → 7True
    ⋯ 18 more passes ⋯
    283 → 11 → 3True
    292 → 11 → 2True
  6. if not swapped:

    19# If no swaps, array is sorted20if not swappedFalse:21    break
  7. return passes

    23return passes2
  8. almost_sorted ← [1, 2, 3, 4, 5, 6, 7, 8], passes1 ← 2

    31print("Before:", almost_sorted)32passes1→ 2 = bubble_sort_optimized(almost_sorted→ [1, 2, 3, 4, 5, 6, 7, 8])33print("After: ", almost_sorted[1, 2, 3, 4, 5, 6, 7, 8])34print("Passes:", passes12)3536print("\nReverse sorted:")37print("Before:", reversed_list[8, 7, 6, 5, 4, 3, 2, 1])38passes2 = bubble_sort_optimized(reversed_list[8, 7, 6, 5, 4, 3, 2, 1])39print("After: ", reversed_list)
    outputAfter:  [1, 2, 3, 4, 5, 6, 7, 8]
    Passes: 2
    
    Reverse sorted:
    Before: [8, 7, 6, 5, 4, 3, 2, 1]
  9. n ← 8, passes ← 0

    pass 2 of 2
    4def bubble_sort_optimized(arr[8, 7, 6, 5, 4, 3, 2, 1]):5    """Optimized bubble sort with early termination"""6    n→ 8 = len(arr[8, 7, 6, 5, 4, 3, 2, 1])7    passes→ 0 = 0
  10. return passes

    23return passes7
  11. reversed_list ← [1, 2, 3, 4, 5, 6, 7, 8], passes2 ← 7

    37print("Before:", reversed_list)38passes2→ 7 = bubble_sort_optimized(reversed_list→ [1, 2, 3, 4, 5, 6, 7, 8])39print("After: ", reversed_list[1, 2, 3, 4, 5, 6, 7, 8])40print("Passes:", passes27)
    outputAfter:  [1, 2, 3, 4, 5, 6, 7, 8]
    Passes: 7
early_termination Stop early if no swaps occur in a pass, meaning list is sorted

Descending Order

descending.py
Replay: real traced execution (multi-file project)
# Sort descending


def bubble_sort_ascending(arr):
    """Sort in ascending order"""
    n = len(arr)
    for i in range(n - 1):
        for j in range(n - i - 1):
            # Ascending: swap if left > right
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


def bubble_sort_descending(arr):
    """Sort in descending order"""
    n = len(arr)
    for i in range(n - 1):
        for j in range(n - i - 1):
            # Descending: swap if left < right
            if arr[j] < arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]


# Test both directions
numbers1 = [64, 34, 25, 12, 22]
numbers2 = [64, 34, 25, 12, 22]

bubble_sort_ascending(numbers1)
print("Ascending: ", numbers1)

bubble_sort_descending(numbers2)
print("Descending:", numbers2)

  1. numbers1 ← [64, 34, 25, 12, 22], numbers2 ← [64, 34, 25, 12, 22]

    24# Test both directions25numbers1→ [64, 34, 25, 12, 22] = [64, 34, 25, 12, 22]26numbers2→ [64, 34, 25, 12, 22] = [64, 34, 25, 12, 22]2728bubble_sort_ascending(numbers1[64, 34, 25, 12, 22])29print("Ascending: ", numbers1)
  2. n ← 5

    4def bubble_sort_ascending(arr[64, 34, 25, 12, 22]):5    """Sort in ascending order"""6    n→ 5 = len(arr[64, 34, 25, 12, 22])7    for i in range(n - 1):
  3. for i in range(n - 1):

    pass 1 of 4
    6n = len(arr)7for i0 in range(n5 - 1):8    for j in range(n - i - 1):9        # Ascending: swap if left > right
    All 4 passes — pass 1 is the card above
    passi
    10
    21
    32
    43
  4. for j in range(n - i - 1): # Ascending: swap if left > rig…

    pass 1 of 10
    7for i in range(n - 1):8    for j0 in range(n5 - i0 - 1):9        # Ascending: swap if left > right10        if arr[j] > arr[j + 1]:11            arr[j], arr[j + 1] = arr[j + 1], arr[j]
    All 10 passes — pass 1 is the card above
    passji
    100
    210
    320
    430
    501
    611
    721
    802
    912
    1003
  5. arr[j] ← 34, arr[j + 1] ← 64

    pass 1 of 9
    9# Ascending: swap if left > right10if arr[j]64 > arr[j + 1]34:11    arr[j]→ 34, arr[j + 1]→ 64 = arr[j + 1], arr[j]
    All 9 passes — pass 1 is the card above
    passarr[j]arr[j + 1]
    164 → 3434 → 64
    264 → 2525 → 64
    364 → 1212 → 64
    464 → 2222 → 64
    534 → 2525 → 34
    634 → 1212 → 34
    734 → 2222 → 34
    825 → 1212 → 25
    925 → 2222 → 25
  6. numbers1 ← [12, 22, 25, 34, 64]

    28bubble_sort_ascending(numbers1→ [12, 22, 25, 34, 64])29print("Ascending: ", numbers1[12, 22, 25, 34, 64])3031bubble_sort_descending(numbers2[64, 34, 25, 12, 22])32print("Descending:", numbers2)
    outputAscending:  [12, 22, 25, 34, 64]
  7. n ← 5

    14def bubble_sort_descending(arr[64, 34, 25, 12, 22]):15    """Sort in descending order"""16    n→ 5 = len(arr[64, 34, 25, 12, 22])17    for i in range(n - 1):
  8. for i in range(n - 1):

    pass 1 of 4
    16n = len(arr)17for i0 in range(n5 - 1):18    for j in range(n - i - 1):19        # Descending: swap if left < right
    All 4 passes — pass 1 is the card above
    passiarr[j]arr[j + 1]
    1012 → 2222 → 12
    21——
    32——
    43——
  9. for j in range(n - i - 1): # Descending: swap if left < ri…

    pass 1 of 10
    17for i in range(n - 1):18    for j0 in range(n5 - i0 - 1):19        # Descending: swap if left < right20        if arr[j] < arr[j + 1]:21            arr[j], arr[j + 1] = arr[j + 1], arr[j]
    All 10 passes — pass 1 is the card above
    passjiarr[j]arr[j + 1]
    100——
    210——
    320——
    43012 → 2222 → 12
    501——
    611——
    721——
    802——
    912——
    1003——
  10. arr[j] ← 22, arr[j + 1] ← 12

    19# Descending: swap if left < right20if arr[j]12 < arr[j + 1]22:21    arr[j]→ 22, arr[j + 1]→ 12 = arr[j + 1], arr[j]
  11. numbers2 ← [64, 34, 25, 22, 12]

    31bubble_sort_descending(numbers2→ [64, 34, 25, 22, 12])32print("Descending:", numbers2[64, 34, 25, 22, 12])
    outputDescending: [64, 34, 25, 22, 12]

Counting Comparisons

comparison_count.py
Replay: real traced execution (multi-file project)
# Count comparisons and swaps


def bubble_sort_counted(arr):
    """Bubble sort that counts operations"""
    n = len(arr)
    comparisons = 0
    swaps = 0

    # Count operations
    for i in range(n - 1):
        for j in range(n - i - 1):
            comparisons += 1
            if arr[j] > arr[j + 1]:
                swaps += 1
                arr[j], arr[j + 1] = arr[j + 1], arr[j]

    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 = bubble_sort_counted(sorted_list.copy())
print(f"Already sorted: {comp1} comparisons, {swap1} swaps")

comp2, swap2 = bubble_sort_counted(reversed_list.copy())
print(f"Reverse sorted: {comp2} comparisons, {swap2} swaps")

comp3, swap3 = bubble_sort_counted(random_list.copy())
print(f"Random order:   {comp3} comparisons, {swap3} swaps")

  1. sorted_list ← [1, 2, 3, 4, 5], reversed_list ← [5, 4, 3, 2, 1]

    21# Test on different inputs22sorted_list→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]23reversed_list→ [5, 4, 3, 2, 1] = [5, 4, 3, 2, 1]24random_list→ [3, 1, 4, 2, 5] = [3, 1, 4, 2, 5]2526comp1, swap1 = bubble_sort_counted(sorted_list[1, 2, 3, 4, 5].copy())27print(f"Already sorted: {comp1} comparisons, {swap1} swaps")
  2. n ← 5, comparisons ← 0, swaps ← 0

    pass 1 of 3
    4def bubble_sort_counted(arr[1, 2, 3, 4, 5]):5    """Bubble sort that counts operations"""6    n→ 5 = len(arr[1, 2, 3, 4, 5])7    comparisons→ 0 = 08    swaps→ 0 = 0
    All 3 passes — pass 1 is the card above
    passarrncomparisonsswaps
    1[1, 2, 3, 4, 5]500
    2[5, 4, 3, 2, 1]500
    3[3, 1, 4, 2, 5]500
  3. for i in range(n - 1):

    pass 1 of 12
    10# Count operations11for i0 in range(n5 - 1):12    for j in range(n - i - 1):13        comparisons += 1
    All 12 passes — pass 1 is the card above
    passi
    10
    21
    32
    43
    50
    61
    72
    83
    90
    101
    112
    123
  4. comparisons ← 1

    pass 1 of 30
    11for i in range(n - 1):12    for j0 in range(n5 - i0 - 1):13        comparisons→ 1 += 114        if arr[j] > arr[j + 1]:
    30 passes — pass 1 is the card above
    passjicomparisons
    1000 → 1
    2101 → 2
    3202 → 3
    4303 → 4
    5014 → 5
    6115 → 6
    7216 → 7
    8027 → 8
    9128 → 9
    ⋯ 19 more passes ⋯
    29128 → 9
    30039 → 10
  5. return comparisons, swaps

    18return comparisons10, swaps0
  6. comp1 ← 10, swap1 ← 0

    26comp1→ 10, swap1→ 0 = bubble_sort_counted(sorted_list[1, 2, 3, 4, 5].copy())27print(f"Already sorted: {comp110} comparisons, {swap10} swaps")2829comp2, swap2 = bubble_sort_counted(reversed_list[5, 4, 3, 2, 1].copy())30print(f"Reverse sorted: {comp2} comparisons, {swap2} swaps")
    outputAlready sorted: 10 comparisons, 0 swaps
  7. swaps ← 1, arr[j] ← 4, arr[j + 1] ← 5

    pass 1 of 13
    13comparisons += 114if arr[j]5 > arr[j + 1]4:15    swaps→ 1 += 116    arr[j]→ 4, arr[j + 1]→ 5 = arr[j + 1], arr[j]
    13 passes — pass 1 is the card above
    passswapsarr[j]arr[j + 1]
    10 → 15 → 44 → 5
    21 → 25 → 33 → 5
    32 → 35 → 22 → 5
    43 → 45 → 11 → 5
    54 → 54 → 33 → 4
    65 → 64 → 22 → 4
    76 → 74 → 11 → 4
    87 → 83 → 22 → 3
    98 → 93 → 11 → 3
    ⋯ 2 more passes ⋯
    121 → 24 → 22 → 4
    132 → 33 → 22 → 3
  8. return comparisons, swaps

    18return comparisons10, swaps10
  9. comp2 ← 10, swap2 ← 10

    29comp2→ 10, swap2→ 10 = bubble_sort_counted(reversed_list[5, 4, 3, 2, 1].copy())30print(f"Reverse sorted: {comp210} comparisons, {swap210} swaps")3132comp3, swap3 = bubble_sort_counted(random_list[3, 1, 4, 2, 5].copy())33print(f"Random order:   {comp3} comparisons, {swap3} swaps")
    outputReverse sorted: 10 comparisons, 10 swaps
  10. return comparisons, swaps

    18return comparisons10, swaps3
  11. comp3 ← 10, swap3 ← 3

    32comp3→ 10, swap3→ 3 = bubble_sort_counted(random_list[3, 1, 4, 2, 5].copy())33print(f"Random order:   {comp310} comparisons, {swap33} swaps")
    outputRandom order:   10 comparisons, 3 swaps

Characteristics

  • Time complexity: O(n^2) - two nested loops
  • Space complexity: O(1) - sorts in place
  • Stable: equal elements maintain relative order
  • Best case: O(n) - already sorted with optimization
  • Worst case: O(n^2) - reverse sorted
quadratic_time O(n^2) means doubling the data quadruples the time

When to Use

  • Teaching sorting concepts
  • Small datasets
  • Nearly sorted data with optimization
  • When simplicity is more important than speed

Exercise: practical.py

Implement bubble sort to sort a list of student records by grade, preserving the original order for students with the same grade