Quick Sort
Quick Sort is a popular divide and conquer sorting algorithm. It picks a pivot, partitions the array so that elements < pivot go to the left and elements > pivot go to the right, then recursively sorts both halves.
Algorithm
- Pick a pivot.
- Partition: Rearrange the array so elements < pivot go left and elements > pivot go right.
- Recursively quicksort the left and right halves.
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
Lomuto Partition (In-Place)
def quicksort(arr, low, high):
if low < high:
pivot_idx = partition(arr, low, high)
quicksort(arr, low, pivot_idx - 1)
quicksort(arr, pivot_idx + 1, high)
def partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
Hoare Partition
def hoare_partition(arr, low, high):
pivot = arr[low]
i = low - 1
j = high + 1
while True:
i += 1
while arr[i] < pivot:
i += 1
j -= 1
while arr[j] > pivot:
j -= 1
if i >= j:
return j
arr[i], arr[j] = arr[j], arr[i]
Example
data = [10, 7, 8, 9, 1, 5]
quicksort(data, 0, len(data) - 1)
print(data) # [1, 5, 7, 8, 9, 10]
Visualization
[10, 7, 8, 9, 1, 5] pivot = 5
Partition: [1, 5, 8, 9, 10, 7] (simplified)
[1, 5] [8, 9, 10, 7]
Partition again
[1, 5] [7, 9, 10, 8]
[7] [8, 10, 9]
[8] [9, 10]
[9] [10]
Result: [1, 5, 7, 8, 9, 10]
Time Complexity
| Case | Time |
|---|---|
| Best | O(n log n) |
| Average | O(n log n) |
| Worst | O(n²) |
The worst case occurs when the pivot is always the smallest/largest element (data already sorted).
Optimization
import random
def quicksort_optimized(arr, low, high):
if low < high:
# Random pivot to avoid the worst case
rand_idx = random.randint(low, high)
arr[rand_idx], arr[high] = arr[high], arr[rand_idx]
pivot_idx = partition(arr, low, high)
quicksort_optimized(arr, low, pivot_idx - 1)
quicksort_optimized(arr, pivot_idx + 1, high)
Quick Sort vs Merge Sort
| Aspect | Quick Sort | Merge Sort |
|---|---|---|
| Worst case | O(n²) | O(n log n) |
| Space | O(log n) | O(n) |
| Cache | More efficient | Less efficient |
| Stable | No | Yes |
| In-place | Yes | No |
Quick Sort is fast in practice. Insertion Sort is better for small data.