Stacks, Queues & Linked Lists
Three structures about controlling the ORDER things come out: stacks (last in, first out), queues (first in, first out), and the linked list that often implements them.
A stack is a pile of plates: push onto the top, pop from the top — last in, first out (LIFO). You already depend on one constantly: the call stack. Every function call pushes a frame; every return pops it; a recursion that never stops overflows it. Stacks also power undo history, the back button, and matching brackets in every editor and compiler.
A queue is a line at a shop: join at the back, served from the front — first in, first out (FIFO). Print jobs, task schedulers, message queues, and breadth-first search (graphs lesson) all use one. Don't use a Python list as a queue — pop(0) shifts everything, O(n). Use collections.deque, which gives O(1) at both ends.
How does deque get O(1) at both ends? Linked lists. A linked list stores each element in its own node with a pointer to the next node — no contiguous block. Insert or remove anywhere you hold a pointer: O(1), just rewire two links, no shifting. The price is the array's superpower reversed: no jumping to index 500 — you must walk there, O(n). Arrays trade cheap access for expensive insertion; linked lists trade the opposite.
In practice you'll rarely hand-roll a linked list — dynamic arrays win most real workloads because contiguous memory is cache-friendly (see the Computer Architecture track). But the node-and-pointer idea is the building block for trees and graphs, which you'll use constantly.