SwadhyAI Notes

All DSA notes

DSA Complexity

Bubble sort cost

A five-bar demo looks "done when no swaps." Then production feeds n = 20,000 reverse-sorted rows and the quadratic pass shows up.

Bubble sort's cost story is comparisons and swaps in the worst case, with an best case of Theta(n). Stable and in-place when coded with a strict comparator.

Algorithm journey

1

Count passes

Up to n - 1 unsettled passes.

2

Count inner compares

About n - p per pass p.

3

Count swaps

Equals the inversion count.

4

Optional early exit

Zero-swap pass proves sorted.

What actually happens

Naive claim: early exit makes bubble "basically linear." Counterexample: one turtle value at the end still forces Theta(n^2) compares.

Better claim: teach inversions and suffix settlement; do not ship it for large n.

Comparison sorts cannot beat Omega(n log n) worst case in general; bubble does not approach that bound.

Invariant

Before pass p, the suffix of length p is final; comparisons in the active prefix cannot beat the quadratic worst case without stronger structure.

How to read bubble sort's complexity

1. Teaching? Excellent. Production large n?|No.

2. Already sorted? Theta(n) with a flag.

3. Few inversions but deep turtles? Still Theta(n^2) compares.

Quantitative check

n = 5,000 reverse-sorted: about 12.5 million comparisons and swaps. Same n already sorted with early exit: 4,999 comparisons, zero swaps.

How it works

1

Compare Adjacent Elements

Start at the beginning of the array and compare the first two elements.

2

Swap if Needed

If the first element is greater than the second, swap them.

3

Move to Next Pair

Move one position forward and repeat the comparison for the next pair.

4

Repeat Until Sorted

Continue passes through the array until no swaps are needed (array is sorted).

Note: Why "Bubble" Sort?

The name comes from the way smaller elements "bubble" to the top (beginning) of the list, while larger elements "sink" to the bottom (end). Each pass guarantees the largest unsorted element reaches its final position - just like air bubbles rising in water!

šŸŽÆ Visual Example

Sorting [5, 2, 8, 1, 9]:

Pass 1:
[5, 2, 8, 1, 9] → [2, 5, 8, 1, 9] (swap)
[2, 5, 8, 1, 9] → [2, 5, 8, 1, 9] (no swap)
[2, 5, 8, 1, 9] → [2, 5, 1, 8, 9] (swap)
[2, 5, 1, 8, 9] → [2, 5, 1, 8, 9] (no swap)
Result: [2, 5, 1, 8, 9] ← 9 in place!
Pass 2:
[2, 5, 1, 8] → [2, 5, 1, 8] (no swap)
[2, 5, 1, 8] → [2, 1, 5, 8] (swap)
[2, 1, 5, 8] → [2, 1, 5, 8] (no swap)
Result: [2, 1, 5, 8, 9] ← 8 in place!
Pass 3:
[2, 1, 5] → [1, 2, 5] (swap)
[1, 2, 5] → [1, 2, 5] (no swap)
Result: [1, 2, 5, 8, 9] ← 5 in place!
Final: [1, 2, 5, 8, 9] āœ“ Sorted!

šŸŽ® Interactive Bubble Sort Demo

Click "Start" to watch the largest bars bubble up to the right side!

Speed:
ā„¹ļø Ready
Comparing/Active
Sorted

šŸŽÆ Key Insight: Optimization with Flag

Basic bubble sort always does n-1 passes, even if the array becomes sorted earlier.Optimized bubble sort uses a flag to detect if any swaps occurred in a pass. If no swaps happened, the array is sorted and we can stop early! This improves best-case to O(n) for already-sorted arrays.

šŸ’» Implementation

Python

python
def bubble_sort(arr):
    """
    Bubble Sort with optimization flag
    
    Time Complexity:
    - Best Case: O(n) - already sorted
    - Average Case: O(n²)
    - Worst Case: O(n²) - reverse sorted
    
    Space Complexity: O(1) - in-place sorting
    """
    n = len(arr)
    
    # Outer loop: n-1 passes maximum
    for i in range(n - 1):
        # Optimization: flag to detect if array is sorted
        swapped = False
        
        # Inner loop: compare adjacent elements
        # Each pass, largest element bubbles to end
        # So we can ignore last i elements (already sorted)
        for j in range(n - 1 - i):
            # Compare adjacent elements
            if arr[j] > arr[j + 1]:
                # Swap if out of order
                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
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"Original: {arr}")

sorted_arr = bubble_sort(arr.copy())
print(f"Sorted: {sorted_arr}")

# Output:
# Original: [64, 34, 25, 12, 22, 11, 90]
# Sorted: [11, 12, 22, 25, 34, 64, 90]


# Demonstrating best case (already sorted)
sorted_arr = [1, 2, 3, 4, 5]
bubble_sort(sorted_arr)  # Only 1 pass needed!
print(f"Already sorted: {sorted_arr}")
# Output: Already sorted: [1, 2, 3, 4, 5]

Java

java
public class BubbleSort {
    /**
     * Bubble Sort with optimization flag
     * 
     * Time Complexity:
     * - Best Case: O(n) - already sorted
     * - Average Case: O(n²)
     * - Worst Case: O(n²) - reverse sorted
     * 
     * Space Complexity: O(1) - in-place sorting
     */
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        boolean swapped;
        
        // Outer loop: n-1 passes maximum
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            
            // Inner loop: compare adjacent elements
            // Each pass, largest element bubbles to end
            // So we can ignore last i elements (already sorted)
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap if out of order
                    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[] arr = {64, 34, 25, 12, 22, 11, 90};
        System.out.println("Original: " + java.util.Arrays.toString(arr));
        
        bubbleSort(arr);
        
        System.out.println("Sorted: " + java.util.Arrays.toString(arr));
    }
}

Invariant and correctness

Pass invariant: after pass i, the i largest elements occupy the final i positions in sorted order. Each adjacent inversion encountered by the inner scan is removed; therefore the maximum remaining element moves to the right boundary. Shrinking that boundary is safe because the suffix cannot change again.

If a complete pass makes no swap, no adjacent inversion exists. An array with no adjacent inversion is sorted, which proves the early-exit condition. Stability depends on using >, not >=: equal keys never cross. It is in-place and adaptive, but not online: an unseen future value can invalidate the current order.

Exact work and adaptivity

Comparisons

At most (nāˆ’1)+(nāˆ’2)+…+1 = n(nāˆ’1)/2. With early exit, a sorted input needs only nāˆ’1.

Swaps

Exactly one adjacent swap per inversion, so swaps equal the inversion count I: from 0 to n(nāˆ’1)/2.

Stronger boundary

Recording the final swap position can skip an already ordered suffix; the asymptotic worst case remains Θ(n²).

⚔ Complexity Analysis

Time Complexity

  • āœ“
    O(n) - Best Case

    Already sorted, only 1 pass needed

  • •
    O(n²) - Average Case

    Random order, ~n²/2 comparisons

  • āœ—
    O(n²) - Worst Case

    Reverse sorted, maximum swaps

Space Complexity

  • āœ“
    O(1)

    In-place sorting, only uses temp variable for swapping

Other Properties

  • āœ“Stable: Maintains relative order of equal elements
  • āœ“In-place: Doesn't need extra array
  • āœ“Adaptive: Faster for nearly-sorted data

Tip: When to Use Bubble Sort

Bubble sort is best treated as a learning instrument or a deliberately bounded primitive:

  • • Education: Makes inversions, stability, and loop invariants visible
  • • Adjacent-exchange constraints: Useful when the operation itself must swap neighbors
  • • Sortedness detection: The no-swap pass demonstrates an adaptive stopping proof
  • • Tiny fixed inputs: Accept only after measurement; insertion sort is usually the stronger baseline

Avoid for: General-purpose sorting and any unbounded or latency-sensitive input.

āœ… Pros & āŒ Cons

āœ… Advantages

  • āœ“Extremely simple to understand and implement
  • āœ“In-place sorting (O(1) extra space)
  • āœ“Stable sort (preserves order of equal elements)
  • āœ“Adaptive (efficient for nearly-sorted data)
  • āœ“No recursion needed (unlike quick/merge sort)

āŒ Disadvantages

  • āœ—Very slow for large datasets (O(n²))
  • āœ—Not practical for real-world applications
  • āœ—Repeated full passes when inversions are far from their destination
  • āœ—Potentially Θ(n²) swaps and heavy write traffic
  • āœ—Outperformed by insertion sort for small arrays

šŸ’¼ Real World Applications

šŸ“š Teaching & Learning

Bubble sort is the go-to algorithm for teaching sorting concepts in computer science courses. Its simplicity makes it perfect for understanding how sorting works.

Example: CS101 introductory courses

šŸ”§ Fixed-size demonstrations

A system with a compile-time tiny bound can tolerate quadratic work, but O(1) space alone is not a reason to choose bubble sort: insertion, selection, heap, and in-place quicksort variants also avoid a second array.

Document the maximum n and worst-case comparison budget.

Practice questions

Often used as a warm-up question in coding interviews to test basic algorithm knowledge and ability to optimize (adding the swap flag).

Example: "Implement and optimize bubble sort"

🧪 Algorithm Visualization

Educational tools and visualizations often use bubble sort because its step-by-step swapping is easy to animate and understand visually.

Example: Sorting algorithm animations

API contract, language traps, and tests

  • The shown function mutates its input. In Python, pass values.copy() when callers require persistence; in Java, document mutation or clone first.
  • For objects, compare immutable keys and never subtract two integer keys in Java: a subtraction comparator can overflow.
  • Stability is observable only with records carrying both a key and original identity; test duplicate keys, not just integer equality.
  • Property tests should assert sorted order, permutation preservation, idempotence, and stable order for equal keys across empty, singleton, sorted, reverse, duplicate-heavy, and random inputs.

Production choice: use the platform sort. Bubble sort is chiefly a teaching tool or a tiny bounded routine where adjacent exchanges are themselves the desired operation, not a general-purpose response to tight memory.

Exercises

  1. Derive n(n-1)/2 for reverse-sorted distinct keys.
  2. Explain why I = n-1 inversions can still yield Theta(n^2) comparisons.
  3. Compare bubble vs insertion best/worst classes side by side.

Primary sources

  • CLRS elementary sorts.
  • Knuth TAOCP Vol. 3: bubble sorting and inversions.
  • Sedgewick & Wayne: elementary sorts lab.

Short takeaway

Bubble Sort = Repeatedly swap adjacent elements if out of order until sorted.Time: O(n²) average/worst, O(n) best with optimization.Space: O(1) in-place.Properties: Stable, adaptive, simple.Use when: Learning, tiny datasets, or memory-constrained.Avoid when: Large datasets or performance matters!