ADT vs. data structure
ADT = interface (what). Data structure = implementation (how). One ADT, many implementations.
ADT typical DS List array, linked list Stack array / linked list Queue linked list / ring buf Priority queue binary heap Set hash table / BST Map / Dictionary hash table / BST Graph adj. list / matrix
The seven structures
-
Array / vector — contiguous; indexing.
-
Linked list — nodes + pointers; insert if you hold the prev.
-
Tree — hierarchical; recursion natural.
-
BST — ordered tree; ops if balanced.
-
Heap — complete binary tree; peek, push/pop.
-
Hash table — bucketed; expected ops.
-
Graph — nodes + edges; adjacency list or matrix.
Searching
Linear search any data Binary search sorted
Binary search midpoint: lo + (hi - lo) / 2 (avoid overflow).
Big-O in one sentence
iff such that for all . Drop constants, drop lower-order terms, keep the dominant term.
Growth hierarchy
Rule of thumb for loops:
-
Single loop over : .
-
Nested over : .
-
Halving each iteration: .
-
Divide-and-conquer (): .
Constant-time operations
v[i], v.back(), push_back (amortized), pop_back, size(), arithmetic, a bounded-iteration loop. Not constant: hashing a long string, a loop whose bound depends on input.
Sorting comparison
Sort best avg worst stable in-place
Bubble yes yes Insertion yes yes Selection no yes Shell var. no yes Merge yes no Quick no yes Heap no yes Radix (LSD) yes no Counting yes no Bucket yes no
Bubble sort is covered in ch_13.1 (extras) --- pedagogy-only, never ship it. Bucket-sort average assumes input is uniformly distributed; full treatment in ch_13.3.
“Which sort do I pick?”
-
Small array () or nearly sorted: insertion sort ( best case, tiny constants).
-
General-purpose, RAM-bound: quicksort (what
std::sortuses, with heapsort fallback). -
Stability required: merge sort (
std::stable_sort). -
External / too big for RAM: merge sort (sequential I/O; the model for external mergesort).
-
Integer keys, bounded width: radix sort (beats comparison-based bound).
-
Tightest worst-case guarantee: heap sort.
The \Omega(n \log n) lower bound
Any comparison-based sort needs comparisons in the worst case. Decision-tree argument: possible outputs, so any binary tree that distinguishes them has depth . Radix and counting sort beat this because they’re non-comparison.
Stable vs. unstable
A sort is stable if equal keys retain their original relative order. Matters when sorting by one field after another (e.g., sort by last name, then stable-sort by city).
In-place
Uses or auxiliary memory. Merge sort’s buffer makes it not in-place; its recursion stack is .
Quicksort: watch the pivot
Average ; worst on already-sorted input with first-element pivot. Fixes: median-of-three; randomize. std::sort uses introsort: quicksort + fallback to heapsort after a depth limit.
Top gotchas
-
Quoting ” always” for quicksort (it’s average; worst case is ).
-
Saying merge sort is in-place (it’s not).
-
Using
strcmp-style comparators for numeric sort. -
Assuming
std::sortis stable (usestd::stable_sort). -
Reasoning about “fast” without bounding .