Quick Sort is a highly efficient, divide-and-conquer, comparison-based sorting algorithm. It is often used in practice because of its average time complexity of , which is faster than many other algorithms, including Merge Sort, for large datasets in most cases. However, Quick Sort’s worst-case time complexity is $$ O(n^2)), which can occur if the pivot selection is not optimal. Despite this, with good pivot selection, Quick Sort is one of the fastest general-purpose sorting algorithms.
Quick Sort works by selecting a pivot element from the array and then partitioning the array around the pivot. The pivot is chosen such that elements smaller than the pivot are on the left side, and elements greater than the pivot are on the right side. This step is called partitioning. After partitioning, the pivot is in its correct position, and we then recursively apply Quick Sort to the left and right subarrays.
Steps:
Here’s how the Quick Sort algorithm works step-by-step:
def quick_sort(arr):
# Base case: if the array has one or zero elements, it's already sorted
if len(arr) <= 1:
return arr
# Choose a pivot (in this case, we take the last element as the pivot)
pivot = arr[len(arr) - 1]
# Partitioning step: elements less than the pivot go to left, greater to the right
left = [x for x in arr[:-1] if x < pivot] # Elements less than pivot
right = [x for x in arr[:-1] if x >= pivot] # Elements greater than or equal to pivot
# Recursively sort left and right and combine with the pivot
return quick_sort(left) + [pivot] + quick_sort(right)
arr[len(arr) - 1]).left contains elements smaller than the pivot.right contains elements greater than or equal to the pivot.left and right subarrays and then combine them with the pivot element in the middle.The partitioning step is the heart of Quick Sort. It rearranges the elements so that all elements smaller than the pivot are on the left side, and all elements greater than the pivot are on the right side. After partitioning, the pivot is in its correct sorted position.
Here's a more efficient implementation of partitioning using in-place swapping:
def quick_sort(arr):
if len(arr) <= 1:
return arr
# Choose the last element as pivot
pivot = arr[-1]
# Partitioning step
i = -1 # Pointer for the smaller element
for j in range(len(arr) - 1):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
# Swap the pivot into the correct position
arr[i + 1], arr[-1] = arr[-1], arr[i + 1]
# Recursively apply to the left and right subarrays
left_sorted = quick_sort(arr[:i + 1])
right_sorted = quick_sort(arr[i + 2:])
return left_sorted + [arr[i + 1]] + right_sorted
Quick Sort has an average time complexity of , but it depends on how the pivot is selected:
Best Case: The pivot divides the array into two roughly equal halves. This occurs when the pivot is always the median element.
Average Case: On average, Quick Sort performs well, dividing the array into roughly equal subarrays. This happens in most random or well-shuffled arrays.
Worst Case: If the pivot is always the smallest or largest element, Quick Sort performs poorly. This happens when the array is already sorted or nearly sorted.
Note: The worst-case performance can be mitigated by choosing a good pivot, such as selecting a random pivot or using the median-of-three method (taking the median of the first, middle, and last elements).
Quick Sort operates in-place, meaning that it doesn’t require extra space proportional to the input size, aside from the recursive function call stack.
The efficiency of Quick Sort largely depends on how we choose the pivot element. Common strategies for choosing the pivot include:
First Element: The first element of the array.
Last Element: The last element of the array.
Middle Element: The middle element of the array.
Random Element: A random element is chosen as the pivot.
Median of Three: The pivot is selected as the median of the first, middle, and last elements.
Quick Sort is a highly efficient sorting algorithm with an average time complexity of . It is based on the divide-and-conquer strategy and involves partitioning an array around a pivot element. Quick Sort performs well for large datasets, especially when a good pivot is chosen, but it can suffer in terms of performance if the pivot is not selected well, leading to the worst-case time complexity of . Despite this, it is widely used in practice due to its average-case efficiency, in-place nature, and cache-friendliness.
Open this section to load past papers