Bubble Sort Time Complexity: Best, Average and Worst Case
- Bubble sort: O(nΒ²) worst and average, O(n) best case (optimised version only). O(1) space β sorts in-place.
- The early-exit optimisation (swapped flag) is what enables O(n) best case. Without it, best case is also O(nΒ²).
- Bubble sort is stable β equal elements maintain their relative order β but so are Timsort and merge sort, which are also O(n log n).
Bubble sort appears in every algorithms course and almost no production codebase. Its value is pedagogical: it's the first algorithm that makes O(nΒ²) complexity intuitive. The optimised variant with early exit is worth implementing cleanly because it demonstrates the most fundamental algorithm optimisation β detect the done condition early and stop.
Bubble Sort: Naive and Optimised Implementations
from typing import List def bubble_sort_naive(arr: List[int]) -> List[int]: """ Naive bubble sort β always does nΒ² comparisons. Time: O(nΒ²) all cases Space: O(1) """ arr = arr.copy() n = len(arr) for i in range(n): for j in range(n - 1): if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] return arr def bubble_sort_optimised(arr: List[int]) -> List[int]: """ Optimised bubble sort with two improvements: 1. After pass i, the last i elements are in place β skip them. 2. If no swap in a full pass, array is sorted β exit early. Time: O(n) best case (already sorted) O(nΒ²) average and worst case (random / reverse sorted) Space: O(1) """ arr = arr.copy() n = len(arr) for i in range(n): swapped = False for j in range(0, n - i - 1): # Each pass is shorter if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] swapped = True if not swapped: # No swaps β already sorted β done break return arr # Already sorted β O(n): only 1 pass, exits immediately print(bubble_sort_optimised([1, 2, 3, 4, 5])) # [1, 2, 3, 4, 5] β 1 pass # Random β O(nΒ²): multiple passes needed print(bubble_sort_optimised([64, 34, 25, 12, 22, 11, 90])) # [11, 12, 22, 25, 34, 64, 90] # Reverse sorted β worst case O(nΒ²): maximum swaps every pass print(bubble_sort_optimised([5, 4, 3, 2, 1])) # [1, 2, 3, 4, 5] β all n passes required
[11, 12, 22, 25, 34, 64, 90]
[1, 2, 3, 4, 5]
# Comparison of approaches:
# Input: [1,2,3,4,5] (already sorted, n=5)
# Naive optimised: n*(n-1)/2 = 10 comparisons
# Early-exit optimised: n-1 = 4 comparisons (stops after 1 pass)
| Case | Time | When It Occurs |
|---|---|---|
| Best case (optimised) | O(n) | Array already sorted β early exit after 1 pass |
| Best case (naive) | O(nΒ²) | No early exit regardless of input |
| Average case | O(nΒ²) | Random order |
| Worst case | O(nΒ²) | Reverse sorted β maximum swaps every pass |
| Space complexity | O(1) | Sorts in-place β no auxiliary array |
| Stable? | Yes | Equal elements are never swapped |
π― Key Takeaways
- Bubble sort: O(nΒ²) worst and average, O(n) best case (optimised version only). O(1) space β sorts in-place.
- The early-exit optimisation (swapped flag) is what enables O(n) best case. Without it, best case is also O(nΒ²).
- Bubble sort is stable β equal elements maintain their relative order β but so are Timsort and merge sort, which are also O(n log n).
- Never use bubble sort on more than a few hundred elements in production. Language built-ins are always faster.
β Common Mistakes to Avoid
- βUsing the naive O(nΒ²) best-case implementation when the optimised version is the same code complexity β the swapped flag costs nothing and enables the O(n) best case.
- βApplying bubble sort to large inputs β at n=100,000, O(nΒ²) means 10 billion operations. Python's sorted() (Timsort) handles this in O(n log n).
- βThinking bubble sort's stability makes it production-viable β Timsort and merge sort are also stable and O(n log n). Stability alone doesn't justify O(nΒ²).
Interview Questions on This Topic
- QWhat is bubble sort's time complexity in best, average, and worst case?
- QHow does the early-exit optimisation change bubble sort's best-case complexity?
- QCompare bubble sort to insertion sort β when would you prefer one over the other?
Frequently Asked Questions
What is the time complexity of bubble sort?
O(nΒ²) for average and worst case. The best case is O(n) only with the optimised version that includes an early-exit flag β when no swaps occur in a full pass, the array is already sorted and the algorithm exits. The naive version without this optimisation is O(nΒ²) even in the best case.
Is bubble sort stable?
Yes. Bubble sort only swaps adjacent elements when they're in the wrong order. Equal elements are never swapped, so their relative order is preserved. This makes it stable β but Timsort and merge sort are also stable and O(n log n), so stability is not a reason to choose bubble sort.
Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.