Skip to content
C++ Better Explained
Go back
Bubble Sort in C++: How It Works with Full Source Code
Edit page

Bubble Sort in C++: How It Works with Full Source Code

Bubble sort is one of the simplest sorting algorithms to understand — and one of the first you will encounter when learning algorithms. It is not efficient for large datasets, but it is a great starting point for understanding how sorting algorithms work before moving on to faster ones like merge sort or quicksort.

This article explains how bubble sort works, walks through it step by step, provides a full C++ implementation with an optimisation, and covers when you would (and would not) use it.

Video Walkthrough

Watch this video walkthrough of bubble sort in C++:

How Bubble Sort Works

The idea behind bubble sort is simple: repeatedly walk through the array comparing adjacent pairs of elements and swapping them if they are in the wrong order. After each full pass through the array, the largest unsorted element has “bubbled up” to its correct position at the end.

Here is the process step by step:

  1. Compare element at index 0 with element at index 1 — swap if out of order
  2. Compare element at index 1 with element at index 2 — swap if out of order
  3. Continue until the end of the array
  4. Repeat the whole process for the remaining unsorted portion
  5. Stop when a full pass completes with no swaps

Step-by-Step Example

Let’s sort {5, 3, 8, 1, 2}:

Pass 1:

Pass 2:

Pass 3:

Pass 4:


C++ Implementation

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

void bubbleSort(vector<int>& arr) {
    int n = arr.size();

    for (int i = 0; i < n - 1; i++) {
        // Each pass moves the largest unsorted element to its final position
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

int main() {
    vector<int> arr = {5, 3, 8, 1, 2};

    cout << "Before: ";
    for (int x : arr) cout << x << " ";
    cout << endl;

    bubbleSort(arr);

    cout << "After:  ";
    for (int x : arr) cout << x << " ";
    cout << endl;

    return 0;
}

Output:

Before: 5 3 8 1 2
After:  1 2 3 5 8

Optimised Version with Early Exit

The basic implementation always runs all passes even if the array is already sorted. Adding a swapped flag lets the algorithm detect when no swaps occurred and exit early — giving O(n) best-case performance on already-sorted or nearly-sorted data:

void bubbleSortOptimised(vector<int>& 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 no swaps occurred this pass, the array is already sorted
        if (!swapped) break;
    }
}

This is the version you should always use in practice when bubble sort is appropriate.


Code Walkthrough

for (int i = 0; i < n - 1; i++) {

The outer loop runs n - 1 passes. After each pass, one more element is in its final position at the end, so the inner loop shrinks by one each time.

for (int j = 0; j < n - i - 1; j++) {

The inner loop goes up to n - i - 1 because the last i elements are already sorted and don’t need to be compared.

if (arr[j] > arr[j + 1]) {
    swap(arr[j], arr[j + 1]);
}

Compare adjacent elements and swap if the left one is greater. std::swap from <algorithm> handles the swap cleanly.


Time and Space Complexity

CaseTime ComplexityNotes
Best caseO(n)Array already sorted — optimised version exits after one pass
Average caseO(n²)Random data — many comparisons and swaps
Worst caseO(n²)Reverse-sorted array — maximum swaps required
SpaceO(1)In-place — no extra memory needed

Comparison with Other Sorting Algorithms

AlgorithmBestAverageWorstStableIn-place
Bubble sortO(n)O(n²)O(n²)
Insertion sortO(n)O(n²)O(n²)
Selection sortO(n²)O(n²)O(n²)
Merge sortO(n log n)O(n log n)O(n log n)
std::sortO(n log n)O(n log n)O(n log n)

Bubble sort performs similarly to insertion sort on most inputs, but insertion sort is generally faster in practice because it does fewer writes to memory. Both are outclassed by std::sort for any real workload.


When to Use Bubble Sort

Use bubble sort when:

Don’t use bubble sort when:

For production C++ code, always use std::sort from <algorithm>:

#include <algorithm>
#include <vector>

vector<int> arr = {5, 3, 8, 1, 2};
std::sort(arr.begin(), arr.end());


Edit page
Share this post on:

Next Post
C++ File Handling: Reading and Writing Files with fstream