DAA Course Material

Quick Sort

A beautiful, interactive guide to understanding one of the most important sorting algorithms in computer science.

What is Quick Sort?

Let's break it down in the simplest way possible.

Real-World Analogy

Imagine you have a stack of 100 exams and you need to arrange them by score (lowest to highest).

Here's what Quick Sort does:

  1. 1 Pick a reference score (like 75). We call this the "pivot".
  2. 2 Divide exams into two piles: those below 75 and those above 75.
  3. 3 Repeat the same process for each pile until everything is sorted!
THE IDEA IN ONE SENTENCE

"Pick a reference, divide into smaller groups, sort each group the same way."

Divide Conquer Combine

Fast in Practice

One of the fastest sorting algorithms for real-world data. Used everywhere from databases to video games!

Memory Efficient

Can sort "in-place" - meaning it doesn't need extra memory proportional to the input size.

Elegant Code

The algorithm is beautifully simple and can be implemented in just a few lines of code.

Core Concept

Understanding the two key ideas behind Quick Sort

Divide and Conquer Strategy

Quick Sort uses a technique called "Divide and Conquer" - a powerful problem-solving approach.

1

Divide

Split the problem into smaller, independent sub-problems

2

Conquer

Solve each sub-problem recursively (the same way!)

3

Combine

Combine the solutions (in Quick Sort, this is automatic!)

The Partition Process

The heart of Quick Sort is the partition operation. Let's understand it step by step:

Original array:
7 2 1 6 8 5 3 4

★ Choose Pivot

Select an element to serve as the "reference point."

7 2 6 ← Pivot (last element)

← → Two Pointers

Use two pointers to scan from both ends.

7 2 6 8 5

📌 The Partition Rules:

i

Left Pointer (i)

Moves right, finds elements > pivot

j

Right Pointer (j)

Moves left, finds elements < pivot

When both stop: Swap the elements. Continue until pointers cross.

Interactive Visualization

Watch Quick Sort in action, step by step

Pivot
Comparing
Swapping
Sorted
Array Size: 10
Speed: 3x

Click "Start Sorting" to begin

0
Comparisons
0
Swaps
0
Partitions
0.00s
Time

The Algorithm

Pseudocode and implementation details

pseudocode.txt
// Main QuickSort function
function quickSort(arr, low, high):
    if low < high:
        // Partition the array
        pivotIndex = partition(arr, low, high)
        
        // Recursively sort left part
        quickSort(arr, low, pivotIndex - 1)
        
        // Recursively sort right part
        quickSort(arr, pivotIndex + 1, high)

// Partition function
function partition(arr, low, high):
    // Choose last element as pivot
    pivot = arr[high]
    
    // i tracks the boundary of "smaller" elements
    i = low - 1
    
    // j scans through the array
    for j = low to high - 1:
        if arr[j] <= pivot:
            i = i + 1
            swap(arr[i], arr[j])
    
    // Place pivot in correct position
    swap(arr[i + 1], arr[high])
    return i + 1

Step-by-Step Explanation

  1. 1 Base Case: If the subarray has 0 or 1 elements, it's already sorted.
  2. 2 Partition: Rearrange elements so smaller ones are on the left, larger on the right.
  3. 3 Recursive Left: Apply QuickSort to the left subarray (elements smaller than pivot).
  4. 4 Recursive Right: Apply QuickSort to the right subarray (elements larger than pivot).

Key Points to Remember

  • The pivot's final position is correct after each partition
  • Elements left of pivot are ≤ pivot; right are > pivot
  • No combine step needed - partitions are already in correct order!

In-Place Sorting

Quick Sort is an in-place algorithm, meaning it doesn't require extra space proportional to the input size. The partitioning rearranges elements within the original array!

Pivot Selection Strategies

1st

First Element

Always pick arr[low]

⚠️ Bad for sorted arrays

Last

Last Element

Always pick arr[high]

✓ Most common in teaching

Random

Pick a random element

✓ Good average case

Med

Median of 3

Median of first, middle, last

✓ Best in practice

Complexity Analysis

Understanding how efficient Quick Sort really is

Best Case
O(n log n)

When the pivot always divides the array into roughly equal halves.

When does this happen?
When pivot is always (or nearly) the median element.

Average Case
O(n log n)

For randomly ordered arrays. This is what we expect in practice!

Why?
log n levels of recursion, each level does O(n) work.

Worst Case
O(n²)

When pivot is always smallest or largest element.

When does this happen?
Already sorted/reverse sorted array with first/last pivot.

Space Complexity

Iterative (with explicit stack) O(log n)
Recursive (average) O(log n)
Recursive (worst) O(n)

The extra space comes from the call stack in recursive implementation.

Properties

Stable ❌ No
In-Place ✓ Yes
Comparison-based ✓ Yes
Adaptive ❌ No

Comparison with Other Sorting Algorithms

Algorithm Best Average Worst Space Stable
Quick Sort O(n log n) O(n log n) O(n²) O(log n) No
Merge Sort O(n log n) O(n log n) O(n log n) O(n) Yes
Heap Sort O(n log n) O(n log n) O(n log n) O(1) No
Bubble Sort O(n) O(n²) O(n²) O(1) Yes

Test Your Understanding

Practice what you've learned

Quick Quiz

Question 1 of 5

Common Interview Questions

Quick Sort is preferred for arrays because: (1) It's in-place, requiring O(log n) extra space vs O(n) for Merge Sort; (2) It has better cache locality; (3) It's typically faster in practice despite the same average complexity. However, Merge Sort is preferred for linked lists.
Several strategies: (1) Use randomized pivot selection; (2) Use "median of three" pivot selection; (3) Switch to Heap Sort when recursion depth exceeds a threshold (IntroSort); (4) Shuffle the array before sorting.
No, Quick Sort is not stable. The partitioning step can change the relative order of equal elements. For example, if we have [2a, 1, 2b] and pivot is 2b, after partition we get [1, 2b, 2a], changing the order of the two 2s. This happens because elements may be swapped across the pivot during partitioning.
For small arrays (typically n < 10-20), Insertion Sort is faster due to lower overhead. This is why many implementations (like Java's Arrays.sort) use Insertion Sort for small subarrays within Quick Sort.