Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
📘 Lesson  ·  Lesson 77

Bubble Sort

Written and reviewed by · Senior IT Faculty · 15+ years’ experience

Bubble Sort Concept and Loop Invariant

Bubble sort scans adjacent pairs, swaps a pair that is out of order, and repeats passes until no disorder remains. After one complete ascending pass, the largest element in the active range is at its final position. That statement is the pass invariant and explains why the next pass can ignore the sorted suffix.

Core rule

For ascending order, compare values[i] with values[i+1]; swap only when the first is greater. Each swap removes at least one adjacent inversion.

The result must be ordered and must contain exactly the original elements. This is more important than merely producing the expected output for one example. Compare this elementary method with selection and insertion sort.

Pass-by-Pass Trace

Sort {5, 1, 4, 2, 8} in ascending order:

PassImportant swapsSequence after passFixed suffix
15↔1, 5↔4, 5↔21 4 2 5 88
24↔21 2 4 5 85 8
3None1 2 4 5 8Whole range sorted

The third pass makes no swap, so an optimized implementation stops. Without early exit, the output is still correct but needless comparisons continue.

Algorithm and Pseudocode

for end = size down to 2
    swapped = false
    for i = 0 while i + 1 < end
        if values[i] > values[i + 1]
            swap the two values
            swapped = true
    if swapped is false
        stop

end is exclusive. After a pass, values[end-1] is final, so decreasing end is safe. Empty and one-element ranges require no special branch because the outer loop does not run.

Complete Optimized Bubble Sort Program

#include <iostream>
#include <utility>
#include <vector>

void bubble_sort(std::vector<int>& values) {
    for (std::size_t end = values.size(); end > 1; --end) {
        bool swapped = false;
        for (std::size_t i = 0; i + 1 < end; ++i) {
            if (values[i] > values[i + 1]) {
                std::swap(values[i], values[i + 1]);
                swapped = true;
            }
        }
        if (!swapped) {
            break;
        }
    }
}

int main() {
    std::vector<int> values{5, 1, 4, 2, 8};
    bubble_sort(values);

    std::cout << "Sorted:";
    for (int value : values) {
        std::cout << ' ' << value;
    }
    std::cout << '\n';
}
Sorted: 1 2 4 5 8

The function accepts the vector by non-const reference because it intentionally modifies the caller's data. std::size_t matches container sizes, and the end > 1 guard avoids unsigned underflow.

Early Exit and Last-Swap Optimization

The swapped flag changes the best case from quadratic work to one linear pass. A further refinement remembers the position of the last swap: everything after that position was already ordered, so the next active range can end there.

std::size_t end = values.size();
while (end > 1) {
    std::size_t last_swap = 0;
    for (std::size_t i = 1; i < end; ++i) {
        if (values[i - 1] > values[i]) {
            std::swap(values[i - 1], values[i]);
            last_swap = i;
        }
    }
    end = last_swap;
}

This can reduce comparisons on partially sorted data, but it does not change the Θ(n²) average and worst-case growth.

Complexity, Stability and Correctness

PropertyOptimized bubble sort
Best timeΘ(n), already sorted
Average timeΘ(n²)
Worst timeΘ(n²), reverse-like order
Auxiliary spaceO(1)
StableYes with strict > comparison
AdaptiveYes, with early exit

Correctness follows from two facts: each pass fixes the largest active element, and swaps preserve the multiset of input values. When a pass makes no swap, every adjacent pair is nondecreasing; by transitivity, the whole range is sorted.

When to Use Bubble Sort

Bubble sort is valuable for visualizing invariants, swaps, stability and asymptotic analysis. It may be acceptable for a tiny range, a classroom demonstration, or code where adjacent exchanges are the exact subject being studied. It is a poor default for large arrays.

NeedBetter choice
General fast in-memory sortingstd::sort
Preserve equivalent-element orderstd::stable_sort
Predictable Θ(n log n) teaching algorithmMerge sort
Small/nearly sorted sequenceInsertion sort is often more practical

Also study the STL algorithms guide before writing a custom production sorter.

Common Mistakes, Tests and Practice

MistakeCorrection
Inner loop reaches i == end-1Require i+1 < end
Resetting swapped inside inner loopReset once per pass
Using >=Use strict > to retain stability
Unsigned loop decrements below zeroUse an explicit end > 1 condition
Claiming O(n) without early exitState which implementation is analyzed

Test set: empty, one element, sorted, reverse sorted, all equal, duplicates, negative values and a large random range. Practice: count comparisons and swaps; implement descending order; implement the last-swap boundary; verify stability using records with equal keys.

Authoritative References

The definition, complexity classification and standard-library comparison were checked against these sources. Continue with sorting and searching in C++.

Frequently Asked Questions

What is the time complexity of bubble sort?
Optimized bubble sort takes Θ(n) time on already sorted input and Θ(n²) in the average and worst cases. It uses O(1) auxiliary space.
Is bubble sort stable?
Yes, the usual version is stable when it swaps only when the left value is strictly greater than the right value. Swapping equal values can destroy stability.
Is bubble sort an in-place algorithm?
Yes. It rearranges elements inside the original sequence and needs only a few variables, so its auxiliary-space requirement is O(1).
Why is a swapped flag used?
If a complete pass makes no swap, every adjacent pair is already ordered and the sequence is sorted. The flag lets the algorithm stop immediately.
Should bubble sort be used in production C++?
Usually no for general data. Prefer std::sort, or std::stable_sort when equivalent elements must retain their order. Bubble sort remains useful for teaching and tiny inputs.

Bubble Sort का Concept और Invariant

Bubble sort adjacent elements compare करता है, गलत order वाले pair को swap करता है और passes दोहराता है। Ascending pass के बाद active range का largest element final position पर पहुंच जाता है; अगला pass sorted suffix को छोड़ सकता है।

मुख्य नियम

values[i] > values[i+1] होने पर ही swap करें। Strict comparison equal records का relative order बचाता है।

Selection और insertion से तुलना के लिए यह lesson पढ़ें।

Pass-by-Pass Trace

PassSwapsPass के बाद sequence
15↔1, 5↔4, 5↔21 4 2 5 8
24↔21 2 4 5 8
3कोई नहीं1 2 4 5 8

तीसरे pass में swap नहीं हुआ, इसलिए optimized algorithm तुरंत stop करता है।

Algorithm

हर pass में active range के adjacent pairs compare करें
out-of-order pair swap करें
pass के बाद end एक position घटाएं
किसी pass में swap न हो तो stop करें

Empty और single-element vector में loop नहीं चलता, इसलिए result natural रूप से सही रहता है।

Complete C++ Program

void bubble_sort(std::vector<int>& values) {
    for (std::size_t end = values.size(); end > 1; --end) {
        bool swapped = false;
        for (std::size_t i = 0; i + 1 < end; ++i) {
            if (values[i] > values[i + 1]) {
                std::swap(values[i], values[i + 1]);
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}
Input: 5 1 4 2 8 Sorted: 1 2 4 5 8

Full program में <iostream>, <utility> और <vector> include करें। Reference parameter caller के vector को in-place sort करता है।

Early-Exit Optimization

हर outer pass से पहले swapped=false करें। Swap होने पर true करें। Pass के अंत में false रहे तो सभी adjacent pairs ordered हैं, इसलिए best case Θ(n) हो जाता है। Last swap का index रखकर अगला boundary और छोटा किया जा सकता है, पर worst case Θ(n²) ही रहता है।

Complexity और Stability

PropertyResult
BestΘ(n), early exit के साथ
Average/WorstΘ(n²)
Extra spaceO(1)
Stableहाँ, strict > पर
In-placeहाँ

Swap input elements को खोता या बनाता नहीं। हर pass largest active value fix करता है; no-swap pass पूरे sequence के ordered होने का प्रमाण है।

कब Use करें

Teaching, visualization और tiny inputs में उपयोगी है। Large general data के लिए std::sort, stable order के लिए std::stable_sort, और Θ(n log n) अध्ययन के लिए merge sort बेहतर हैं। STL algorithms भी पढ़ें।

Mistakes, Testing और Practice

  • i+1 < end रखें, वरना out-of-bounds access होगा।
  • swapped एक pass में एक बार reset करें।
  • Stability के लिए >= नहीं, > लें।
  • Sorted, reverse, duplicates, negative, empty और one-element cases test करें।

Practice: comparisons/swaps count करें, descending version लिखें और equal-key records से stability verify करें।

Authoritative संदर्भ

Definition और complexity इन sources से verify की गई हैं। अगला topic: sorting और searching

← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.