Skip to main content

Comparison Based Sorting

Bubble Sort: Algorithm, Dry Run, Code & Complexity Explained

What is Bubble Sort?

Bubble Sort repeatedly compares adjacent elements and swaps them if they are in the wrong order. With each pass, the largest unsorted element bubbles up to its correct position at the end of the array.

Algorithm Steps

  1. Start from index 0, compare arr[j] and arr[j+1]
  2. If arr[j] > arr[j+1], swap them
  3. After one full pass, the largest element reaches its final position
  4. Repeat for n-1 passes, reducing inner range by 1 each time

Code Implementation

šŸ Python

def bubble_sort(arr):
    n = len(arr)
    for i in range(n - 1):           # n-1 passes
        for j in range(n - i - 1):   # shrink inner range each pass
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

# Optimized version
def bubble_sort_optimized(arr):
    n = len(arr)
    for i in range(n - 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 not swapped:
            break
    return arr

ā˜• Java

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {          // n-1 passes
            for (int j = 0; j < n - i - 1; j++) {  // shrink each pass
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    // Optimized version
    public static void bubbleSortOptimized(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            boolean swapped = false;
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) break;  // already sorted
        }
    }
}

āš™ļø C++

 
#include <iostream>
#include <vector>
using namespace std;

void bubbleSort(vector& arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {          // n-1 passes
        for (int j = 0; j < n - i - 1; j++) {  // shrink each pass
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

// Optimized version
void bubbleSortOptimized(vector& arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (!swapped) break;  // already sorted
    }
}

🟔 JavaScript

function bubbleSort(arr) {
    const n = arr.length;
    for (let i = 0; i < n - 1; i++) {          // n-1 passes
        for (let j = 0; j < n - i - 1; j++) {  // shrink each pass
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // swap
            }
        }
    }
    return arr;
}

// Optimized version
function bubbleSortOptimized(arr) {
    const n = arr.length;
    for (let i = 0; i < n - 1; i++) {
        let swapped = false;
        for (let j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                swapped = true;
            }
        }
        if (!swapped) break;  // already sorted
    }
    return arr;
}

// Test
console.log(bubbleSort([20, 15, 10, 35, 30, 2]));
// Output: [2, 10, 15, 20, 30, 35]

Dry Run — arr = [20, 15, 10, 35, 30, 2]

Comparing
Swapped
Sorted (final)

Pass 0 — 5 comparisons

Initial array:

20
idx 0
15
idx 1
10
idx 2
35
idx 3
30
idx 4
2
idx 5
jCompareActionArray after
020 vs 15āœ… Swap[15, 20, 10, 35, 30, 2]
120 vs 10āœ… Swap[15, 10, 20, 35, 30, 2]
220 vs 35āŒ No swap[15, 10, 20, 35, 30, 2]
335 vs 30āœ… Swap[15, 10, 20, 30, 35, 2]
435 vs 2āœ… Swap[15, 10, 20, 30, 2, 35]

After pass 0:

15
idx 0
10
idx 1
20
idx 2
30
idx 3
2
idx 4
35
idx 5 āœ“

āœ… 35 is in its final position!

Pass 1 — 4 comparisons

jCompareActionArray after
015 vs 10āœ… Swap[10, 15, 20, 30, 2, 35]
115 vs 20āŒ No swap[10, 15, 20, 30, 2, 35]
220 vs 30āŒ No swap[10, 15, 20, 30, 2, 35]
330 vs 2āœ… Swap[10, 15, 20, 2, 30, 35]
10
idx 0
15
idx 1
20
idx 2
2
idx 3
30
idx 4 āœ“
35
idx 5 āœ“

Pass 2 — 3 comparisons

jCompareActionArray after
010 vs 15āŒ No swap[10, 15, 20, 2, 30, 35]
115 vs 20āŒ No swap[10, 15, 20, 2, 30, 35]
220 vs 2āœ… Swap[10, 15, 2, 20, 30, 35]
10
idx 0
15
idx 1
2
idx 2
20
idx 3 āœ“
30
idx 4 āœ“
35
idx 5 āœ“

Pass 3 — 2 comparisons

jCompareActionArray after
010 vs 15āŒ No swap[10, 15, 2, 20, 30, 35]
115 vs 2āœ… Swap[10, 2, 15, 20, 30, 35]
10
idx 0
2
idx 1
15
idx 2 āœ“
20
idx 3 āœ“
30
idx 4 āœ“
35
idx 5 āœ“

Pass 4 — 1 comparison

jCompareActionArray after
010 vs 2āœ… Swap[2, 10, 15, 20, 30, 35]
2
idx 0 āœ“
10
idx 1 āœ“
15
idx 2 āœ“
20
idx 3 āœ“
30
idx 4 āœ“
35
idx 5 āœ“

šŸŽ‰ Sorted: [2, 10, 15, 20, 30, 35]

Comparisons Summary

Pass (i)Inner rangeComparisons
0n-1 = 55
1n-2 = 44
2n-3 = 33
3n-4 = 22
4n-5 = 11
Total15 = n(n-1)/2

Time & Space Complexity

CaseTimeReason
BestO(n)Already sorted — 0 swaps (optimized)
AverageO(n²)Random order
WorstO(n²)Reverse sorted — maximum swaps
SpaceO(1)In-place — only a temp swap variable

Is Bubble Sort Stable?

āœ… Yes. We only swap when arr[j] > arr[j+1] (strict greater than). Equal elements are never swapped, preserving their relative order.