Insertion • Quick • Merge • Bucket
def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key
def quick_sort(arr): def median_of_three(lo, hi): mid = (lo + hi) // 2 triple = [(arr[lo], lo), (arr[mid], mid), (arr[hi], hi)] triple.sort(key=lambda x: x[0]) return triple[1][1] def qs(lo, hi): if lo >= hi: return pivot_index = median_of_three(lo, hi) arr[pivot_index], arr[hi] = arr[hi], arr[pivot_index] pivot = arr[hi] i = lo for j in range(lo, hi): if arr[j] <= pivot: arr[i], arr[j] = arr[j], arr[i] i += 1 arr[i], arr[hi] = arr[hi], arr[i] qs(lo, i - 1) qs(i + 1, hi) qs(0, len(arr) - 1)
def merge_sort(arr): if len(arr) > 1: mid = len(arr) // 2 left = arr[:mid] right = arr[mid:] merge_sort(left) merge_sort(right) i = j = k = 0 while i < len(left) and j < len(right): if left[i] <= right[j]: arr[k] = left[i] i += 1 else: arr[k] = right[j] j += 1 k += 1 while i < len(left): arr[k] = left[i] i += 1 k += 1 while j < len(right): arr[k] = right[j] j += 1 k += 1
def counting_sort(arr): if not arr: return arr k = max(arr) # assumes non-negative integers counts = [0] * (k + 1) for x in arr: counts[x] += 1 i = 0 for v, c in enumerate(counts): for _ in range(c): arr[i] = v i += 1
Stable means that if two elements have the same key or value, they keep the same relative order in the output as in the input.
Algorithm | Best | Average | Worst | Space | Stable |
---|---|---|---|---|---|
Insertion | O(n) | O(n²) | O(n²) | O(1) | Yes |
Quick | O(n log n) | O(n log n) | O(n²) | O(1) | No |
Merge | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes |
Bucket | O(n + k) | O(n + k) | O(n + k) | O(k) | * |
* Bucket Sort: Stable if implemented with cumulative counts (stable placement). Here, k is the range of distinct integer keys (max value − min value + 1).