/

Bubble Sort

Bubble sort is a simple comparison-based sorting algorithm that repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. The pass through the list is repeated until the list is sorted. It gets its name because smaller elements "bubble" to the top of the list with each iteration.

Sorting O(n²) Stable

How Bubble Sort Works

Bubble sort works by making multiple passes through an array. On each pass, it compares each pair of adjacent elements and swaps them if they are in the wrong order. After the first pass, the largest element is guaranteed to be at the end of the array. After the second pass, the second-largest is in place, and so on.

Step-by-step process:

  • Start at the beginning: Begin with the first element in the array. Compare it with the next element.
  • Compare adjacent elements: If the current element is greater than the next element, swap them. Otherwise, move on.
  • Continue through the array: Repeat this comparison for every adjacent pair until the end of the array. This completes one "pass."
  • Largest element bubbles up: After each pass, the largest unsorted element is now in its correct position at the end of the unsorted portion.
  • Repeat: Continue making passes through the array, each time ignoring the already-sorted elements at the end.
  • Early exit optimization: If a complete pass is made with no swaps, the array is already sorted and the algorithm can terminate early. This optimization makes the best-case time complexity O(n) for an already-sorted array.

While bubble sort is easy to understand and implement, it is not efficient for large datasets. Its O(n²) average and worst-case time complexity makes it impractical compared to algorithms like merge sort or quicksort for large arrays. However, its simplicity makes it an excellent teaching tool for understanding sorting algorithms.

Interactive Visualization

Watch how bubble sort compares and swaps adjacent elements pass by pass. Yellow bars indicate the pair being compared, orange bars indicate a swap, and green bars are in their final sorted position.

Press Play or Step to start the visualization.
Speed No steps

Code Implementation

Below is an optimized bubble sort implementation in three languages. The optimization includes an early exit flag: if no swaps occur during a pass, the array is already sorted and we can stop immediately.

def bubble_sort(arr):
    """Optimized bubble sort with early exit."""
    n = len(arr)
    for i in range(n - 1):
        swapped = False
        # Last i elements are already in place
        for j in range(n - 1 - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
        # If no swaps occurred, array is sorted
        if not swapped:
            break
    return arr


# Example usage
numbers = [64, 34, 25, 12, 22, 11, 90, 45]
print("Unsorted:", numbers)
print("Sorted:  ", bubble_sort(numbers))
public class BubbleSort {

    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            boolean swapped = false;
            // Last i elements are already in place
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap arr[j] and arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            // If no swaps occurred, array is sorted
            if (!swapped) break;
        }
    }

    public static void main(String[] args) {
        int[] numbers = {64, 34, 25, 12, 22, 11, 90, 45};
        System.out.print("Unsorted: ");
        printArray(numbers);

        bubbleSort(numbers);

        System.out.print("Sorted:   ");
        printArray(numbers);
    }

    private static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            if (i < arr.length - 1) System.out.print(", ");
        }
        System.out.println();
    }
}
#include <iostream>
#include <vector>
using namespace std;

void bubbleSort(vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        // Last i elements are already in place
        for (int j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        // If no swaps occurred, array is sorted
        if (!swapped) break;
    }
}

void printArray(const vector<int>& arr) {
    for (int i = 0; i < arr.size(); i++) {
        cout << arr[i];
        if (i < arr.size() - 1) cout << ", ";
    }
    cout << endl;
}

int main() {
    vector<int> numbers = {64, 34, 25, 12, 22, 11, 90, 45};
    cout << "Unsorted: ";
    printArray(numbers);

    bubbleSort(numbers);

    cout << "Sorted:   ";
    printArray(numbers);
    return 0;
}

Complexity Analysis

Bubble sort's performance depends on the initial order of the elements. The optimized version with the early-exit flag achieves O(n) in the best case when the array is already sorted, since only one pass with zero swaps is needed.

Metric Complexity Notes
Best Case Time O(n) Array is already sorted (with early exit optimization)
Average Case Time O(n²) Elements are in random order
Worst Case Time O(n²) Array is sorted in reverse order
Space Complexity O(1) In-place sorting, only uses a temporary variable for swaps
Stable Yes Equal elements maintain their relative order

Practice Problems

Strengthen your understanding of sorting by working through these problems. While bubble sort itself may not be the optimal solution, these problems will help you think about sorting concepts and when different approaches are appropriate.

Sort an Array Medium LeetCode 912 →
Sort Colors Medium LeetCode 75 →
Squares of a Sorted Array Easy LeetCode 977 →

Quiz

Test your understanding of bubble sort with these questions.

Q1. What is the worst-case time complexity of bubble sort?

O(n)
O(n²)
O(n log n)
O(log n)
In the worst case (reverse-sorted array), bubble sort must compare every pair in each pass. There are n-1 passes and up to n-1 comparisons per pass, giving O(n²) total comparisons.

Q2. What optimization can make bubble sort's best-case time complexity O(n)?

Using a binary search to find the swap position
Sorting from both ends simultaneously
Adding a flag to detect if no swaps occurred during a pass
Using a linked list instead of an array
By keeping a boolean flag that tracks whether any swaps were made during a pass, we can terminate early if the array is already sorted. If no swaps occur in a complete pass, the array is in order and we can stop, achieving O(n) for an already-sorted input.

Q3. Is bubble sort a stable sorting algorithm?

Yes, because it only swaps adjacent elements when they are strictly out of order
No, because it moves elements across the array
It depends on the implementation
Only when used with an early exit flag
Bubble sort is stable because it only swaps adjacent elements when arr[j] > arr[j+1] (strictly greater). Equal elements are never swapped, so their original relative order is preserved.

Q4. After the first complete pass of bubble sort on the array [5, 3, 8, 1, 2], which element is guaranteed to be in its correct position?

The smallest element (1)
The largest element (8)
The first element (5)
No element is guaranteed to be in the correct position
After the first pass of bubble sort, the largest element always "bubbles up" to the last position. In this array, 8 will end up at index 4 (the end), which is its correct sorted position. The array after pass 1 would be [3, 5, 1, 2, 8].

Q5. How many passes does bubble sort need to completely sort the array [2, 1, 3, 4, 5] using the optimized version with early exit?

4 passes
1 pass
5 passes
2 passes
Pass 1: Compares (2,1) and swaps to get [1, 2, 3, 4, 5]. The rest of the comparisons in pass 1 find no more swaps needed, but the pass still continues to the end. Pass 2: No swaps occur at all during the entire pass, so the early exit flag triggers and the algorithm terminates. Total: 2 passes.