Master Quick Sort - O(n log n) Divide & Conquer
Learn quick sort with interactive visualizations. Watch partitioning around pivots, explore recursion trees, and understand why it's the fastest sorting algorithm in practice.
Quick Sort Visualization
Enter array values to visualize
Use sample data or custom input
Array Input & Controls
Code Implementation
def quick_sort(arr, low=0, high=None):
"""
Quick Sort with Lomuto partition scheme
Time: O(n log n) average, O(n²) worst
Space: O(log n) recursion stack
"""
if high is None:
high = len(arr) - 1
if low < high:
# Partition and get pivot index
pi = partition(arr, low, high)
# Recursively sort left and right
quick_sort(arr, low, pi - 1)
quick_sort(arr, pi + 1, high)
return arr
def partition(arr, low, high):
# Choose last element as pivot
pivot = arr[high]
i = low - 1 # Partition index
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
# Place pivot in correct position
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
# Usage
arr = [64, 34, 25, 12, 22, 11, 90]
print(quick_sort(arr)) # [11, 12, 22, 25, 34, 64, 90]Big O Complexity
Divide and conquer - logarithmic depth
Recursion stack space
Complexity Cases
Balanced partitions - pivot divides evenly
Random pivots - expected performance
Unbalanced partitions - sorted with bad pivot
Recursion Tree
When to Use Quick Sort
Quick sort is the go-to algorithm for general-purpose sorting with excellent average-case performance.
General Purpose
Most programming languages use quick sort variants in their standard libraries. C qsort(), Python sorted() internals.
Cache-Friendly
In-place partitioning provides excellent cache locality, making it faster than merge sort on modern CPUs.
Large Arrays
O(n log n) average case with O(log n) space makes it ideal for sorting millions of elements efficiently.
Database Systems
Used in query optimization and index building. Quick select variant finds k-th smallest element in O(n) average.
Parallel Computing
Naturally parallelizable - left and right partitions can be sorted independently on different threads/cores.
When NOT to Use
Avoid when stability is required, guaranteed O(n log n) needed, or data is already sorted with poor pivot choice.
Pivot Selection Strategies
| Strategy | Best Case | Worst Case | Use When |
|---|---|---|---|
| Last Element | O(n log n) | O(n²) sorted | Educational, random data |
| Random | O(n log n) | O(n²) rare | Production, unknown patterns |
| Median-of-Three | O(n log n) | O(n²) unlikely | Best balance, standard library |
Quick Sort Algorithm: Master O(n log n) Divide-and-Conquer Sorting
Learn quick sort with interactive visualizations showing pivot selection, partitioning, and recursion. Understand why quick sort is the fastest sorting algorithm in practice, used in C++ STL sort(), Java Arrays.sort(), and production systems worldwide.
What Is Quick Sort? (The Fastest Practical Sorting Algorithm)
Quick sort is a highly efficient divide-and-conquer sorting algorithm that achieves O(n log n) average time complexity with O(log n) space. It works by selecting a "pivot" element, partitioning the array so smaller elements go left and larger elements go right, then recursively sorting both partitions. Despite O(n²) worst case, quick sort is faster than merge sort and heap sort in practice due to excellent cache locality and low constant factors—making it the algorithm of choice for C++ std::sort(), C++ STL sort, and UNIX qsort().
The key to quick sort's performance is pivot selection strategy. Random pivot guarantees O(n log n) expected time regardless of input, median-of-three provides balanced partitions for common patterns, while last element pivot degrades to O(n²) on sorted data. Our interactive tool demonstrates all four strategies with live recursion depth tracking and partition visualization.
Why Quick Sort Dominates in Real-World Applications:
Performance Advantages
- • Cache-friendly: In-place sorting with sequential memory access
- • Fastest average case: Beats merge sort by 2-3x in practice
- • O(log n) space: Minimal memory overhead vs merge sort's O(n)
- • Parallelizable: Left/right partitions sort independently
Industry Adoption
- • C++ STL: Introsort (quick sort + heap sort fallback)
- • Java: Dual-pivot quick sort for primitives
- • Linux kernel: Sort algorithm for kernel data structures
- • Databases: Used in query optimization and indexing
Quick Sort vs Other Algorithms: Real Examples
[64,34,25,12,22,11,90] O(n log n) average, 18 comparisons, 8 swaps, depth 3[1,2,3,4,5,6,7] + last pivot O(n²) degradation, 21 comparisons, depth 6 (unbalanced)How to Learn Quick Sort in 3 Steps
💡 Pro Tip: Choosing the Right Pivot Strategy
Random pivot is best for unknown input patterns—guarantees O(n log n) expected time and prevents adversarial worst-case inputs. Median-of-three (median of first/middle/last) works well for partially sorted data and is used in production libraries. Avoid last/first pivot on sorted data unless combined with randomization or size threshold switching to insertion sort for small subarrays (introsort pattern).
4 Pivot Selection Strategies (Critical for Performance)
Always chooses arr[high] as pivot. Advantage: Simple implementation used in textbooks. Disadvantage: Degrades to O(n²) on already sorted or reverse sorted arrays—each partition only removes one element. Use only for educational purposes or random data. See worst case in action: try [1,2,3,4,5,6,7] with last pivot—recursion depth hits 6 instead of expected 3.
Randomly selects any element as pivot using randomized algorithms. Advantage: Guarantees O(n log n) expected time regardless of input pattern—makes worst case statistically impossible. Used by: Quickselect algorithm for finding k-th smallest element in O(n) average. Trade-off: Small RNG overhead per partition. Recommended for production systems with untrusted input.
Examines first, middle, and last elements—chooses the median value. Advantage: Provides good pivot selection with O(1) overhead, handles partially sorted data well, avoids worst case on common patterns. Used by: C++ STL std::sort() (introsort variant), Java DualPivotQuicksort. Best practice: Combine with size threshold—switch to insertion sort for subarrays < 10 elements for maximum performance.
Always chooses arr[low] as pivot. Similar to last element strategy—simple but vulnerable to O(n²) on sorted input. Historical note: Early quick sort implementations used this approach before randomization became standard. Modern implementations avoid this due to poor performance on real-world data (often partially sorted).
7 Real-World Quick Sort Applications
1. System Programming and Operating Systems
Linux kernel uses quick sort for sorting kernel data structures due to in-place operation and O(log n) stack space. File systems use quick sort variants for directory entry sorting. Device drivers sort interrupt handling priorities. Our array data structures tutorial covers memory layout optimizations that make quick sort cache-friendly.
2. Database Query Optimization
Databases use quick sort for ORDER BY clauses, index building, and join operations. PostgreSQL implements introsort (quick sort with heap sort fallback) for sorting query results. The O(n log n) average case handles millions of records efficiently. Combine with our merge sort tutorial to understand external sorting for datasets larger than RAM.
3. Programming Language Standard Libraries
C++: std::sort() uses introsort (quick sort + heap sort) | Java: Arrays.sort() uses dual-pivot quick sort for primitives | C: qsort() standard library function | Python: Uses Timsort but quickselect for statistics.median()
4. Competitive Programming and Technical Interviews
Quick sort appears in FAANG interviews for testing divide-and-conquer understanding. LeetCode #215 "K-th Largest Element" uses quickselect (quick sort variant) for O(n) average solution. Understanding pivot selection, partitioning, and recursion is critical for solving 50+ LeetCode problems tagged "divide and conquer."
5. Big Data Processing and Analytics
Hadoop MapReduce uses quick sort for shuffle phase sorting. Apache Spark sorts RDD partitions with TimSort (insertion + merge) but uses quickselect for median calculations. Quick sort's O(log n) space is crucial for distributed systems with memory constraints. Learn more about scalable algorithms in our algorithms section.
6. Graphics and Game Development
Game engines sort objects by depth/distance for rendering order using quick sort (fast average case). Collision detection systems sort bounding boxes along axes. Unity and Unreal Engine use introsort for sorting game objects by priority. The cache-friendly nature makes quick sort ideal for real-time applications requiring 60 FPS.
7. Machine Learning Preprocessing
Scikit-learn uses quick sort for sorting features during decision tree splits. K-NN algorithms sort distances to find nearest neighbors. Quickselect finds medians for data normalization without full sorting. NumPy's np.partition() uses quickselect for O(n) partial sorting.
Quick Sort vs Merge Sort vs Heap Sort (Performance Comparison)
| Algorithm | Best Case | Average | Worst Case | Space | Stable? | Cache |
|---|---|---|---|---|---|---|
| Quick Sort | O(n log n) | O(n log n) | O(n²)* | O(log n) | No | Excellent |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes | Good |
| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | No | Poor |
| Bubble Sort | O(n) | O(n²) | O(n²) | O(1) | Yes | Good |
* Quick sort's O(n²) worst case is rare with random pivot selection. Modern implementations (introsort) switch to heap sort after detecting deep recursion, guaranteeing O(n log n) worst case.
🏆 When Quick Sort Wins
Use quick sort when: (1) Average case matters more than worst case, (2) Memory is limited (O(log n) vs merge's O(n)), (3) Cache performance is critical (in-place), (4) Data fits in RAM, (5) You need parallelization. Use merge sort when: Stability required, guaranteed O(n log n) needed, external sorting (data on disk). Use heap sort when: Guaranteed O(n log n) + O(1) space needed. Practice all three with our interactive algorithm visualizers.
Advanced Quick Sort Variants (Production Algorithms)
Introsort (C++ STL Implementation)
Combines quick sort + heap sort + insertion sort. Starts with quick sort, monitors recursion depth—switches to heap sort if depth exceeds 2 log n (prevents O(n²)), uses insertion sort for subarrays < 16 elements. Guarantees: O(n log n) worst case. Used by: C++ std::sort(), Rust's slice::sort().
Dual-Pivot Quick Sort
Uses two pivots to partition into three segments (< P1, P1 ≤ x ≤ P2, > P2). Advantage: 10-20% faster than single-pivot due to fewer comparisons and better instruction pipelining. Used by: Java Arrays.sort() for primitives since Java 7. Reference: Yaroslavskiy's paper.
3-Way Quick Sort (Dutch National Flag)
Partitions into three: < pivot, = pivot, > pivot. Ideal for: Arrays with many duplicates (reduces to O(n) when all elements equal). Example: Sorting enum values, categorizing data with few unique values. Invented by Dijkstra for the Dutch National Flag problem.
Quickselect (Find K-th Element)
Quick sort variant that finds k-th smallest element in O(n) average without fully sorting. Applications: Finding median, percentiles, top-k problems. LeetCode problems: #215 (K-th Largest), #973 (K Closest Points). Recursively partition but only recurse on the side containing k.
Parallel Quick Sort (Multi-threaded)
After partitioning, sort left and right subarrays on separate threads/cores. Advantage: Natural parallelization—independent partitions. Used in: OpenMP parallel sort, Intel TBB parallel_sort(). Achieves near-linear speedup on multi-core systems for large datasets (> 10⁶ elements).
Iterative Quick Sort (No Recursion)
Uses explicit stack instead of recursion to avoid stack overflow. Advantage: Safer for embedded systems with limited stack space. Optimization: Always push larger subarray first, sort smaller immediately—guarantees O(log n) space even for worst-case input.
5 Quick Sort Implementation Mistakes (And How to Avoid Them)
1. Using Last/First Pivot on Production Data
Real-world data is often partially sorted (database queries, logs, time series). Last/first pivot degrades to O(n²) on sorted input—stack overflows on 10,000+ elements. Fix: Use random pivot or median-of-three. Test with already-sorted arrays during development to catch this early.
2. Not Handling Duplicates Efficiently
Basic quick sort performs poorly on arrays with many duplicates (still O(n²) behavior). Fix: Implement 3-way partitioning (Dutch National Flag) to group equal elements in one pass—reduces to O(n) for arrays with few unique values. Essential for sorting enums, categories, or low-cardinality data.
3. Deep Recursion Without Stack Limit Protection
O(n²) worst case creates O(n) recursion depth—stack overflow on 50,000+ elements. Fix: Implement introsort pattern: track recursion depth, switch to heap sort when depth > 2 log n. Or use iterative quick sort with explicit stack. Modern C++ std::sort() uses this protection.
4. Ignoring Small Subarray Threshold
Quick sort has higher constant factors than insertion sort for small arrays. Recursing down to single elements wastes time. Fix: Switch to insertion sort when subarray size < 10-16 elements (tune via benchmarks). This "hybrid sort" is 20-30% faster—used in all production implementations. Our insertion sort tutorial explains why it's faster for small n.
5. Assuming Stability (Quick Sort Is NOT Stable)
Quick sort can change relative order of equal elements during partitioning. Problem: Sorting complex objects by secondary keys may break primary sort order. Fix: Use merge sort for stable sorting, or store original indices and sort by (value, index) pairs. Database ORDER BY clauses often require stability.
Master Data Structures & Algorithms with Interactive Tools
Build complete algorithm knowledge with our visualization suite—perfect for interview prep at Google, Meta, Amazon, Microsoft:
Ready to Master Quick Sort?
Learn quick sort interactively with step-by-step visualizations, 4 pivot strategies, recursion tree tracking, and production code in 6 languages. Perfect for technical interviews, algorithm courses, and understanding why quick sort dominates real-world systems.
Trusted by 50,000+ developers learning algorithms for FAANG interviews