Category: Sorting
Topics: divide and conquer, in-place sorting, average-case performance, partitioning
A divide-and-conquer sorting algorithm that selects a pivot element and partitions the array so elements smaller than the pivot are on the left and larger on the right, then recursively sorts the subarrays.
def quicksort(arr, low=0, high=None):
if high is None:
high = len(arr) - 1
if low < high:
pivot_idx = partition(arr, low, high)
quicksort(arr, low, pivot_idx - 1)
quicksort(arr, pivot_idx + 1, high)
return arr
def partition(arr, low, high):
"""Lomuto partition scheme"""
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 (faster in practice)
def hoare_partition(arr, low, high):
pivot = arr[(low + high) // 2]
i, j = low - 1, 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]
# Randomized quicksort (avoids worst case)
import random
def randomized_quicksort(arr, low=0, high=None):
if high is None:
high = len(arr) - 1
if low < high:
# Random pivot selection
rand_idx = random.randint(low, high)
arr[rand_idx], arr[high] = arr[high], arr[rand_idx]
pivot_idx = partition(arr, low, high)
randomized_quicksort(arr, low, pivot_idx - 1)
randomized_quicksort(arr, pivot_idx + 1, high)
return arr
# Usage
arr = [64, 34, 25, 12, 22, 11, 90]
quicksort(arr) # [11, 12, 22, 25, 34, 64, 90]
| Case | Complexity |
|---|---|
| Best | O(n log n) |
| Average | O(n log n) |
| Worst | O(n²) |
O(log n) average for recursion stack. O(n) worst case with unbalanced partitions. In-place - no auxiliary array needed.