Complexity & Big-O Quick Reference
Compact reference tables for time and space complexities of all major data structures and algorithms.
In production engineering and competitive programming, physical hardware limits enforce a strict computational budget: modern enterprise CPUs execute approximately elementary operations per second on a single thread.
Knowing the exact asymptotic bounds, memory footprints, and architectural preconditions of standard data structures and algorithms allows software architects to determine whether an approach will succeed before writing a single line of code.
This chapter provides comprehensive, master reference tables for data structures, sorting algorithms, graph algorithms, and range-query engines, complete with 64-bit memory footprints and cache-efficiency metrics.
Learning Objectives
#By the end of this chapter, you will be able to:
- Correlate input scale constraints () with viable algorithmic complexity classes under a 1-second CPU budget.
- Evaluate the worst-case, average-case, and amortized time bounds for 16 primary data structures across index access, search, insertion, and deletion.
- Select sorting algorithms based on theoretical stability, auxiliary memory overhead, and information-theoretic lower bounds ().
- Choose appropriate graph algorithms based on structural preconditions (cycles, negative edge weights, directed acyclic constraints).
- Compare advanced range-query engines (Segment Trees, Fenwick Trees, Sparse Tables) across preprocessing, point update, and range query time profiles.
1. Hardware Physics & The 1-Second CPU Operations Budget
#Wall-clock execution time is fundamentally bounded by the memory hierarchy and CPU instruction pipeline. While a 3.5 GHz CPU completes raw clock cycles per second, instruction pipelining, branch mispredictions, and memory cache misses reduce effective throughput to approximately operations per second for algorithmic logic.
| Memory Hierarchy Level | Hardware Latency (Cycles) | Latency Multiplier | Architectural Locality Impact |
|---|---|---|---|
| CPU Registers | ~1 cycle | (Baseline) | Immediate single-cycle instruction execution |
| L1 Data Cache | 4 – 5 cycles | ~1.1–1.4 ns core cache hit (at 3.5 GHz; sub-nanosecond at >5.0 GHz) | |
| L2 Cache | 12 – 14 cycles | Private per-core cache line access | |
| L3 Shared Cache | 40 – 60 cycles | Cross-core unified cache interrogation | |
| Main DRAM Memory | 150 – 250 cycles | Major pipeline bubble; execution pipeline completely stalled |
Rough Competitive Programming Feasibility Heuristics
#When presented with an input constraint under a standard 1.0-second runtime limit, use this table as an engineering and contest heuristic to narrow candidate algorithmic paradigms:
💡 Heuristic Principle:
These mappings are practical engineering rules of thumb, not immutable mathematical laws. Real-world feasibility depends directly on language overhead (e.g., C++ vs. Python), constant factor multipliers, CPU cache locality, SIMD branch predictability, and specific judge memory/time limits.
| Input Scale Constraint | Estimated Feasible Complexity | Archetypal Algorithmic Strategy | Canonical Examples |
|---|---|---|---|
| or | Factorial permutations, brute-force search | Traveling Salesperson (brute force) | |
| or | Bitmask dynamic programming, backtracking | TSP via Held-Karp, Meet-in-the-Middle | |
| High-order polynomial dynamic programming | 4-Sum brute check, 4D DP state transitions | ||
| Cubic dynamic programming, all-pairs paths | Floyd-Warshall APSP, Matrix Chain Multiplication, Gaussian Elimination | ||
| Quadratic nested loops, pairwise comparisons | Insertion Sort, 2D Grid DP, Bellman-Ford | ||
| Square root decomposition, block queries | Mo's Algorithm, Light/Heavy Decomposition | ||
| or | Divide-and-conquer, heap operations, sorting | MergeSort, QuickSort, Segment Trees, Dijkstra | |
| Linear scan, two pointers, sliding window | Kadane's Algorithm, Prefix Sums, Kahn's BFS | ||
| Sublinear factorization, square root search | Trial division primality testing | ||
| or | Logarithmic divide, binary search, math formulas | Binary search, GCD, modular exponentiation |
2. Master Data Structures Operations Table
#Conventions: = element count, = tree height ( balanced, degenerate), = hash load factor. denotes amortized time.
| Data Structure | Access (Index) | Search (Value) | Insertion (Head) | Insertion (Tail) | Insertion (Arbitrary) | Deletion (Head) | Deletion (Tail) | Deletion (Arbitrary) | Auxiliary Space | 64-Bit Memory Overhead Per Element |
|---|---|---|---|---|---|---|---|---|---|---|
| Static Array | — | — | — | — | — | — | 0 bytes (Raw contiguous primitive bytes) | |||
| Dynamic Array (Vector) | (Excess capacity buffer) | |||||||||
| Singly Linked List | 8 bytes (next pointer + struct padding) | |||||||||
| Doubly Linked List | 16–20 bytes (next and prev pointers) | |||||||||
| Stack (Array Backed) | — | [Push] | — | — | [Pop] | — | — | Contiguous buffer overhead | ||
| Queue (Circular Buffer) | — | — | [Enq] | — | [Deq] | — | — | Fixed circular array slots | ||
| Deque (Double Ended) | Chunked array map pointers | |||||||||
| Hash Table (Chaining) | — | — | — | Bucket array + linked list node pointers | ||||||
| Hash Table (Open Addr) | — | — | — | — | — | Flat table array (Zero pointer overhead) | ||||
| Binary Search Tree | — | — | — | — | — | 16–24 bytes (left, right, parent) | ||||
| AVL Tree (Self-Balancing) | — | — | — | — | — | 20–28 bytes (Pointers + height field) | ||||
| Red-Black Tree | — | — | — | — | — | 17–24 bytes (Pointers + 1-bit color flag) | ||||
| Binary Min/Max Heap | [Peek] | — | — | [Push] | [Pop] | — | 0 bytes (Implicit complete binary array) | |||
| Trie (Prefix Tree) | — | — | — | [Insert] | — | — | [Delete] | per node ( alphabet) | ||
| Disjoint Set Union (DSU) | — | — | — | [Union] | — | — | — | Two flat integer arrays (parent, rank) |
Assuming a maintained tail reference pointer.
Assuming a direct pointer reference to the target node is provided.
Amortized bound. is the Inverse Ackermann function ( for all practical inputs ).
3. Master Sorting Algorithms Benchmark Table
#[!IMPORTANT] Information-Theoretic Lower Bound for Comparison Sorting:
Any comparison-based sorting algorithm can be modeled as a binary decision tree where each leaf corresponds to one of the input permutations.
- A binary tree of height has at most leaves:
- By Stirling's Approximation ():
Therefore, no comparison sorting algorithm can beat in the worst case.
| Algorithm | Best Time | Average Time | Worst Time | Auxiliary Space | In-Place? | Stable? | Algorithmic Paradigm | Recommended Production Use Case |
|---|---|---|---|---|---|---|---|---|
| Bubble Sort | Yes | Yes | Comparison / Exchange | Academic pedagogy only | ||||
| Selection Sort | Yes | No | Comparison / Selection | Minimizing physical memory writes ( swaps) | ||||
| Insertion Sort | Yes | Yes | Comparison / Insertion | Small datasets () or nearly-sorted data | ||||
| Merge Sort | No | Yes | Divide & Conquer | External sorting, sorting linked lists ( space) | ||||
| Quick Sort | Yes | No | Divide & Conquer / Partition | General-purpose in-memory sorting | ||||
| Heap Sort | Yes | No | Selection / Binary Heap | Systems with hard real-time latency and strict space | ||||
| Counting Sort | No | Yes | Non-Comparison / Distribution | Integers within a small bounded range () | ||||
| Radix Sort (LSD) | No | Yes | Non-Comparison / Positional | Fixed-width keys (e.g., 32-bit integers, IP addresses) | ||||
| Bucket Sort | No | Yes | Non-Comparison / Bucketing | Uniformly distributed floating-point numbers | ||||
| TimSort | No | Yes | Adaptive Hybrid (Merge + Insert) | Default standard in Python (sort()) and Java (Arrays.sort()) | ||||
| IntroSort | Yes | No | Hybrid (Quick + Heap + Insert) | Default standard in C++ STL (std::sort) |
4. Master Graph Algorithms Reference Table
#Conventions: (vertex count), (edge count).
| Algorithm | Problem Addressed | Time Complexity | Auxiliary Space | Graph Preconditions & Constraints |
|---|---|---|---|---|
| Breadth-First Search (BFS) | Shortest path in unweighted graphs | Any graph; finds minimal edge-count paths | ||
| Depth-First Search (DFS) | Reachability, cycle detection, bridges | Any graph; call stack bounded by | ||
| Kahn's Topological Sort | Topological linear ordering | Graph must be a DAG (zero directed cycles) | ||
| Dijkstra (Binary Heap) | Single-Source Shortest Paths (SSSP) | Edge weights must be non-negative () | ||
| Dijkstra (Fibonacci Heap) | Single-Source Shortest Paths (SSSP) | Non-negative edge weights; high constant factors | ||
| Bellman-Ford | SSSP & Negative Cycle Detection | Detects negative weight cycles reachable from source | ||
| Floyd-Warshall | All-Pairs Shortest Paths (APSP) | Graph must contain zero negative weight cycles | ||
| Prim's Algorithm | Minimum Spanning Tree (MST) | Connected, undirected graph | ||
| Kruskal's Algorithm | Minimum Spanning Tree (MST) | Connected, undirected graph; utilizes DSU | ||
| Tarjan's SCC | Strongly Connected Components | Directed graph; single DFS pass using discovery & low-link values | ||
| Kosaraju's SCC | Strongly Connected Components | Directed graph; requires transposed reverse graph | ||
| Edmonds-Karp | Maximum Network Flow | Directed graph with non-negative capacity constraints | ||
| Dinic's Algorithm | Maximum Network Flow | Level graphs with blocking flows ( on unit networks) |
5. Master Range Query Data Structures Table
#When answering repeated range queries (Range Sum, Range Minimum/Maximum Query) over dynamic or static arrays of size :
| Data Structure | Preprocessing Time | Range Query Time | Point Update Time | Range Update Time | Space Complexity | Supported Operations |
|---|---|---|---|---|---|---|
| Prefix Sum Array | Static invertible operations (Sum, XOR) | |||||
| Difference Array | Batch range additions with offline queries | |||||
| Sparse Table | Static idempotent operations (RMQ: Min, Max, GCD) | |||||
| Binary Indexed Tree (Fenwick) | Dynamic prefix queries (Sum, Inversions) | |||||
| Segment Tree (Standard) | Any associative operation (Sum, Min, Max, Matrix) | |||||
| Segment Tree (Lazy Prop) | Dynamic range updates + dynamic range queries | |||||
| Square Root Decomposition | Arbitrary dynamic queries, offline Mo's algorithm |
6. Decision Flowchart: Selecting the Right Data Structure
#7. Key Takeaways & Architectural Heuristics
#- The Operations Heuristic: On standard benchmark judges, targeting for the maximum given constraint serves as a dependable rule of thumb for sub-second execution (subject to cache locality and instruction complexity).
- Memory Alignment Matters: Contiguous primitive arrays have zero pointer overhead and maximize L1/L2 cache prefetching; linked nodes incur 16–24 bytes of pointer overhead per element and cause cache stalls.
- Comparison Sort Limit: No comparison-based sort can beat in the worst case; beating this bound requires non-comparison distribution methods (Counting Sort, Radix Sort).
- Idempotency in Range Queries: If the query function is idempotent ( such as ), a Sparse Table answers queries in strict time.
References & Academic Attribution
#- Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2022). Introduction to Algorithms (4th ed.). MIT Press.
- Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley.
- Williams, J. W. J. (1964). Algorithm 232: Heapsort. Communications of the ACM, 7(6), 347–348.
- Tarjan, R. E. (1975). Efficiency of a good but not linear set union algorithm. Journal of the ACM, 22(2), 215–225.