Skip to content
dsa/roadmap
← All cheat sheets
03

Searching & Sorting

dsa.fetehadin.com
3.1 Linear Search

Check every item from left to right until you find the key or run out. Works on any array, sorted or not, but costs O(n).

Best caseO(1): key at index 0
Average case (found)(n + 1)/2 comparisons → O(n)
Worst caseO(n): last item or not present
Needs sorted data?No
SpaceO(1)
  • ✗Returning -1 inside the loop (in an else), which stops after checking only the first item.
  • ✗Looping with i <= n, one past the end.
  • ✗Forgetting that an unsorted array cannot use binary search.
3.2 Binary Search

On a sorted array, check the middle, then throw away the half that cannot contain the key. Each step halves the problem, so it takes O(log n).

Best caseO(1): key is at the first mid
Average / worst caseO(log n): about ⌊log₂ n⌋ + 1 comparisons
1,000,000 itemsat most 20 comparisons
Needs sorted data?Yes, and random access (an array, not a linked list)
SpaceO(1) iterative · O(log n) recursive (call stack)
  • ✗Using while (low < high) instead of low <= high. That misses a key when one item is left.
  • ✗Setting low = mid or high = mid instead of mid ± 1, which can loop forever.
  • ✗Running it on unsorted data. The result is meaningless.
3.3 Selection Sort

Find the smallest remaining item and swap it to the front. Repeat. Simple, at most n − 1 swaps, but always O(n²) comparisons.

Best caseO(n²): it still scans for the minimum every pass
Average caseO(n²)
Worst caseO(n²): n(n−1)/2 comparisons
Swapsat most n − 1 (the fewest of the simple sorts)
SpaceO(1)
Stable · in-placeno · yes
  • ✗Swapping inside the inner loop every time a smaller item is found. Swap once, after the inner loop.
  • ✗Starting the inner loop at j = i instead of j = i + 1 (compares an item with itself).
  • ✗Claiming selection sort has an O(n) best case. It has none; it always scans.
3.4 Bubble Sort

Compare neighbours and swap them if they are out of order. After each pass the biggest remaining item has "bubbled" to the end.

Best case (already sorted)O(n): one pass, no swaps, stop
Average caseO(n²)
Worst case (reversed)O(n²): n(n−1)/2 comparisons and swaps
SpaceO(1)
Stable · in-placeyes · yes
  • ✗Looping j up to n - 1 in every pass instead of n - 1 - i. It still works, but does useless comparisons.
  • ✗Writing a[j] >= a[j+1]. Swapping equal items breaks stability.
  • ✗Reading past the array with j < n and then accessing a[j + 1].
3.5 Insertion Sort

Grow a sorted part on the left by inserting each new item into its correct place, like sorting cards in your hand. Fast on nearly sorted data.

Best case (already sorted)O(n): n − 1 comparisons, 0 shifts
Average caseO(n²)
Worst case (reversed)O(n²): n(n−1)/2 comparisons and shifts
SpaceO(1)
Stable · in-placeyes · yes
  • ✗Writing a[j] >= key in the while loop. That breaks stability.
  • ✗Forgetting j >= 0 in the loop condition, which reads a[-1].
  • ✗Putting a[j + 1] = key inside the while loop. It goes after the loop.
3.6 Pointer Sort

When records are big, don't move them. Sort an array of pointers (or indices) to the records instead, and only small addresses get swapped.

Comparisonssame as the underlying sort (here selection: n(n−1)/2)
Data moved per swapone pointer (8 bytes) instead of one whole record
TimeO(n²) with selection sort; O(n log n) with a fast sort
SpaceO(n) for the pointer array
Stable · in-placeno · no
  • ✗Swapping the records (swap(*p[i], *p[min])) instead of the pointers (swap(p[i], p[min])). That defeats the purpose.
  • ✗Comparing the pointers themselves (p[j] < p[min]) instead of what they point to (p[j]->score).
  • ✗Forgetting to initialise p[i] = &s[i] before sorting.
3.7 Shell Sort

Insertion sort on items a gap apart, with the gap shrinking to 1. Far-away items move in big jumps, so the final insertion sort has little work left.

Best case (sorted)O(n log n)
Average casedepends on the gaps; about O(n^1.5) for n/2, n/4, …
Worst case (gaps n/2, n/4, …)O(n²)
SpaceO(1)
Stable · in-placeno · yes
  • ✗Comparing neighbours (gap 1) in every pass, which is just insertion sort.
  • ✗Forgetting that the last pass must use gap = 1, or the array may not be sorted.
  • ✗Claiming it is stable. Jumps over a gap can reorder equal keys.
3.8 Merge Sort

Split the array in half, sort each half recursively, then merge the two sorted halves. Always O(n log n), stable, but needs O(n) extra space.

Best caseO(n log n)
Average caseO(n log n)
Worst caseO(n log n)
SpaceO(n) for the temporary array
Stable · in-placeyes · no
  • ✗Forgetting to copy the leftover items after one half runs out.
  • ✗Using < instead of <= in merge, which breaks stability.
  • ✗Base case lo > hi only. A single item (lo == hi) must also stop the recursion.
3.9 Quick Sort

Pick a pivot, partition so smaller items go left and bigger items go right, then sort each side recursively. Average O(n log n), worst O(n²).

Best case (pivot splits in half)O(n log n)
Average caseO(n log n)
Worst case (sorted input, last-item pivot)O(n²)
SpaceO(log n) recursion on average, O(n) worst
Stable · in-placeno · yes
  • ✗Recursing on (lo, p) instead of (lo, p − 1). The pivot is already in place.
  • ✗Forgetting the final swap(a[i + 1], a[hi]) that puts the pivot in place.
  • ✗Saying quick sort is always O(n log n).
Stable sort:
A sort that keeps equal keys in their original relative order.
In-place:
Uses only O(1) extra memory besides the input (recursion stack aside).
Pass:
One full sweep of the outer loop of a sort.
Pointer sort:
Sorting an array of pointers (or indices) to records instead of moving the records themselves.
Linear search:
Check each item in turn. O(n). Works on unsorted data.
Binary search:
Repeatedly halve a sorted range by comparing with the middle item. O(log n).
Divide and conquer:
Split a problem into smaller parts, solve them recursively, combine the results.
Pivot:
The item quick sort partitions around.
Partition:
Rearranging a range so items smaller than the pivot come before it and bigger ones after.
Gap (shell sort):
The distance between compared items in a shell sort pass; shrinks to 1.

Keyboard shortcuts

⌘K /
Search topics, glossary, cheat sheets
space
Play / pause the visualizer
← →
Step back / forward
r
Reset the visualizer
?
Show this help