This is a course in data structures and algorithms, written in Python, in
52 posts. It starts at "what is an algorithm" and works up through sorting,
searching, the core data structures, graphs and dynamic programming — and every
post is self-contained, so you can read this in order or arrive from a search
engine and still follow it.
It exists because most DSA material picks one of two failure modes. Either it is
a wall of proofs with no runnable code, or it is a wall of code with the
complexity asserted at the end and never explained. Here, every bound is earned
by a counting argument you can follow, and every implementation runs — the code
in these posts is executed and its printed output checked before publishing.
Who this is for
If you have never programmed, start at post one and read post two before
anything else. Nothing later assumes more Python than that post teaches.
If you already write code but skipped the theory — self-taught, bootcamp,
switching from another field — read the Big O post, then jump to whatever you
need. The sorting posts are the gentlest place to build intuition.
If you are preparing for interviews, the data structures, dynamic programming
and everyday patterns sections are where the questions come from. The summary
table at the end of each post is built for revision.
How each post is built
Every algorithm post follows the same shape, so you always know where to look:
the idea in plain English, a full worked example with diagrams, the complete
Python implementation, a walk through how the code maps to the idea, the
complexity with its justification, honest guidance on when not to use it,
where it turns up in real systems, the mistakes people actually make, practice
problems, and a summary table.
Why Python
Because it is the language that gets out of the way. A binary search in Python
is the algorithm and almost nothing else — no memory management, no type
ceremony, no build step. When the goal is to understand the idea, that matters
more than raw speed. Post two teaches the whole language from scratch if you
need it, including where Python is a poor fit.
The reading order
Foundations
Read these first, in order. Everything else assumes them.
- What Is DSA? Data Structures and Algorithms Explained for Complete Beginners — What the words mean, why the subject matters for real work, and how to think about a problem before you write anything.
- Python From Zero — The whole language from zero: syntax, collections, functions, classes, the standard library, and what Python is actually used for.
- Big O Notation — How to price an algorithm without running it — counting operations, the growth classes, recursion, and amortised cost.
Sorting
The best place to build intuition: nine algorithms solving one problem, with wildly different costs.
- Bubble Sort in Python — The one everyone learns first. Learn it for the counting argument, then never use it.
- Selection Sort in Python — The fewest swaps of any simple sort, and why that occasionally matters.
- Insertion Sort in Python — Quietly excellent on small or nearly-sorted data, which is why real sorts fall back to it.
- Merge Sort in Python — Divide and conquer, and the clearest place to see where n log n comes from.
- Quick Sort in Python — The fastest sort in practice, its quadratic worst case, and how pivot choice fixes it.
- Heap Sort in Python — n log n worst case with no extra memory — the only common sort that manages both.
- Counting Sort in Python — Sorting without a single comparison, and the lower bound it sidesteps.
- Radix Sort in Python — Digit by digit, faster than n log n, when the keys cooperate.
-
Timsort — What
sorted()actually runs: runs, galloping merges, and adaptivity to real data.
Searching
Finding things, and the arithmetic of when it is worth sorting first.
- Linear Search in Python — The simplest algorithm there is, and the arithmetic for when it still beats sorting first.
- Binary Search in Python — Halving the problem each step — plus the off-by-one traps and searching on the answer.
Data structures
How data is arranged determines what is cheap. This is the heart of the subject.
- Arrays and Dynamic Arrays — Why indexing is O(1), why append is amortised O(1), and why inserting at the front is not.
- Linked Lists in Python — Singly, doubly and circular, built from scratch — and an honest word on when not to use one.
- Stacks in Python — Last in, first out: bracket matching, undo, the call stack, and killing recursion.
-
Queues and Deques in Python — First in, first out, why
pop(0)is slow, ring buffers, andcollections.deque. - Hash Tables in Python — How a dictionary reaches O(1): hashing, collisions, load factor and resizing.
- Binary Search Trees in Python — Ordered data with O(h) search — and what happens when h stops being log n.
- AVL Trees and Self-Balancing — Rotations that keep a tree's height logarithmic, and the trees databases use instead.
- Heaps and Priority Queues in Python — Always knowing the smallest item, an array pretending to be a tree, and why building one is O(n).
- Tries in Python — Prefix queries in time proportional to the key, independent of how much is stored.
- Union-Find (Disjoint Set) in Python — Are these two things connected? Answered in near-constant time.
Graphs
Anything that is a network — roads, dependencies, friendships, web links.
- Graphs in Python — Vertices, edges, and choosing between an adjacency list and a matrix.
- Breadth-First Search (BFS) in Python — Level by level, and the shortest path in any unweighted graph.
- Depth-First Search (DFS) in Python — Deep before wide: components, cycles, and the recursion-limit trap.
- Dijkstra's Algorithm in Python — Shortest paths with weights, and exactly why a negative edge breaks it.
- Bellman-Ford in Python — Shortest paths that tolerate negative edges, and detect negative cycles.
- Floyd-Warshall in Python — Every pair at once, in three loops — as long as you nest them in the right order.
- A* Search in Python — Dijkstra plus a heuristic, and what 'admissible' has to mean for it to stay correct.
- Minimum Spanning Trees in Python — Connect everything for the least total weight, two ways, and the property that makes both work.
- Topological Sort in Python — Ordering work that depends on other work — and noticing when that is impossible.
Dynamic programming
The technique people find hardest, broken into a method you can repeat.
- Dynamic Programming Explained — Spotting overlapping subproblems, memoization versus tabulation, and a recipe that generalises.
- The 0/1 Knapsack Problem in Python — The interview classic, the rolling-array trick, and why 'pseudo-polynomial' matters.
- Longest Common Subsequence in Python — The table behind diff tools and sequence alignment.
- Edit Distance (Levenshtein) in Python — How far apart two strings are, and how spellcheckers use it.
- The Coin Change Problem in Python — A coin set where greedy gives the wrong answer, and the DP that does not.
Greedy
Take the best option now. Sometimes provably right, often not.
- Greedy Algorithms Explained — When taking the best option now is provably right — and the counterexamples when it is not.
- Huffman Coding in Python — Frequency-driven prefix codes, and what actually happens inside a ZIP file.
Recursion
The mental model behind dynamic programming, backtracking, trees and divide and conquer.
- Recursion and Backtracking in Python — The call stack, base cases, and the choose / explore / un-choose pattern.
- The N-Queens Problem in Python — Backtracking with pruning, at its clearest.
Strings
Finding a pattern inside text, faster than checking every position.
- The KMP Algorithm in Python — Substring search that never rewinds the text, via the failure table.
- Rabin-Karp in Python — Rolling hashes, spurious hits, and searching for many patterns at once.
Maths
The number-theory algorithms that turn up everywhere from fractions to cryptography.
- The Euclidean Algorithm in Python — Over two thousand years old and still the way to compute a GCD.
- Sieve of Eratosthenes in Python — Every prime below a million, by crossing out rather than testing.
- Fast Exponentiation in Python — Huge powers in log n multiplications, and the modular version cryptography runs on.
Patterns
Not algorithms so much as moves — the ones that turn a quadratic solution linear.
- The Two Pointers Technique in Python — Collapsing a nested loop into a single pass, with the reasoning for why it is safe.
- The Sliding Window Technique in Python — Subarray problems in linear time, and the amortised argument behind the nested while loop.
- Prefix Sums in Python — Constant-time range queries, 2D rectangles, and difference arrays for range updates.
- Building an LRU Cache in Python — A hash map and a linked list, giving O(1) get, put and eviction.
Summary
| Posts | 52 |
| Language | Python 3, standard library only |
| Starts from | No programming experience |
| Foundations | What DSA is, all of Python, Big O and complexity analysis |
| Sorting | 9 algorithms compared side by side |
| Data structures | 10 posts, arrays upwards |
| Graphs | 9 posts: traversal and shortest paths |
| Dynamic programming | 5 posts: the method plus classic problems |
| Every post has | Runnable code, diagrams, complexity derived not asserted, and a summary table |
Start at the beginning if you are new, or pick the thing you needed today. Each
post stands on its own.
Keep reading
- What Is DSA? — start here if any of this is new.
- Python From Zero — the whole language, if you need it first.
- Big O Notation — the one post that makes every other post easier.
- Bubble Sort — the gentlest place to start, and a full counting argument.
- Merge Sort — where O(n log n) actually comes from.
Top comments (0)