Computer Science › Algorithms & Software

Data Structures II

0 of 28
  1. Universal Hashing

    No single fixed hash function can resist an adversary who knows it, so universal hashing draws a fresh function at random from a family guaranteeing collision probability at most 1/m for any pair of keys.

    Read →6 sections10 min
  2. Perfect Hashing

    The FKS two-level construction eliminates collisions entirely, worst-case O(1) lookup with expected O(n) total space, but only for a static set of keys known completely in advance.

    Read →6 sections10 min
  3. Bloom Filters: Probabilistic Set Membership

    A bit array plus k hash functions, with no keys ever stored, gives false positives that are possible but false negatives that are structurally impossible.

    Read →6 sections10 min
  4. False Positive Rate and Optimal Parameters

    The false positive rate is approximately (1 - e^(-kn/m))^k, minimized at k = (m/n)*ln(2), shrinking exponentially as more bits per element are allocated, turning filter sizing into simple arithmetic.

    Read →6 sections8 min
  5. Tries: Prefix Trees for String Keys

    A tree where a key's characters are spelled out one per edge along a root-to-node path — keys sharing a prefix share that prefix's path, something no hash table can offer.

    Read →6 sections15 min
  6. Trie Operations: Insert, Search, Prefix-Match

    Inserting and searching a trie one character at a time, and the operation a hash table fundamentally cannot do efficiently — listing every key that starts with a given prefix.

    Read →6 sections13 min
  7. Ternary Search Tries

    A space-efficient trie variant using three children per node instead of one per alphabet character, trading a little search speed for a dramatically smaller memory footprint.

    Read →6 sections14 min
  8. Real Applications: Autocomplete and Routing Tables

    Two genuine, well-known uses of prefix trees — a search box's autocomplete suggestions, and a router's longest-prefix-match lookup for forwarding IP packets.

    Read →6 sections13 min
  9. The Union-Find (Disjoint-Set) ADT

    A structure for tracking a collection of disjoint groups, supporting exactly two operations — merge two groups, and ask whether two elements are in the same one.

    Read →6 sections12 min
  10. Quick-Find and Quick-Union

    Two naive first attempts at implementing union-find — one makes membership-checking instant but merging slow, the other the reverse — neither good enough on its own.

    Read →6 sections11 min
  11. Union by Rank and Size

    The first key optimization: always attach the smaller (or shallower) tree under the bigger one's root, which alone caps every tree's height at O(log n).

    Read →6 sections12 min
  12. Path Compression

    The second key optimization: while walking up to find a group's root, point every node visited along the way directly at that root, flattening the tree for every future lookup.

    Read →6 sections11 min
  13. Amortized Analysis of Union-Find

    Combined, union by rank and path compression make a sequence of operations run in almost — but not quite exactly — constant time each, a famous result involving the inverse Ackermann function.

    Read →6 sections11 min
  14. The Heap Property

    A binary tree where every node is at least as large as (or at least as small as) both of its children — weaker than a BST's ordering, but exactly enough to make "find the max" instant.

    Read →6 sections14 min
  15. Array Representation of a Binary Heap

    Storing a complete binary tree in a plain array — a node at index i has children at 2i+1 and 2i+2 — avoiding pointers entirely and packing the tree with zero wasted space.

    Read →6 sections13 min
  16. Heap Insert and Extract-Max/Min

    The two operations a priority queue actually needs — adding an element and removing the highest (or lowest) priority one — each done in O(log n) by bubbling along a single root-to-leaf path.

    Read →6 sections13 min
  17. Heapify: Building a Heap in Linear Time

    Turning an arbitrary array into a valid heap in O(n) time, not the O(n log n) a naive one-at-a-time insertion would cost — a genuinely surprising result worth deriving carefully.

    Read →6 sections15 min
  18. Heapsort

    Heapify the whole array once, then repeatedly extract the max into the back of the array — an O(n log n), in-place sort that falls directly out of the heap operations already covered.

    Read →6 sections14 min
  19. Why Balance Matters

    Picking up exactly where Data Structures I left off: a plain BST degrades to O(n) on a lopsided tree, and this discipline exists to fix that guarantee for good.

    Read →6 sections15 min
  20. AVL Trees: The Balance Invariant

    A binary search tree that enforces one simple rule after every insertion or deletion — the heights of any node's two subtrees never differ by more than one.

    Read →6 sections15 min
  21. AVL Rotations: Single and Double

    The local, constant-time restructuring operation — a rotation — that restores AVL's balance invariant after an insertion or deletion knocks it out of alignment.

    Read →6 sections16 min
  22. Red-Black Trees: An Alternative Balance Scheme

    A looser balance invariant, enforced with a color on every node instead of a strict height check — the scheme most production libraries (Java's TreeMap, C++'s std::map) actually use.

    Read →6 sections16 min
  23. Comparing AVL and Red-Black Trees in Practice

    Both guarantee O(log n) operations — the real difference is in the constants: AVL's stricter balance means faster lookups but more rotations; red-black's looser balance means the reverse.

    Read →6 sections14 min
  24. Skip Lists: A Probabilistic Alternative to Balance

    A hierarchy of sorted linked lists, where an element's height is decided by an independent coin flip at insertion, achieving expected O(log n) with no invariant to maintain and no rotation logic at all.

    Read →6 sections10 min
  25. Skip List Search, Insertion, and Deletion

    Insertion and deletion reuse the exact same downward search pass, recording an update array of predecessor nodes per level, with no separate fix-up phase of any kind.

    Read →6 sections9 min
  26. Skip List Expected Height and Why Randomization Works

    An element reaches level k with probability (1/2)^k, giving expected height Θ(log n) and expected O(log n) search, a guarantee over the skip list's own coin flips that no adversarial input can defeat.

    Read →6 sections10 min
  27. Choosing a Data Structure: A Decision Guide

    A side-by-side decision guide across every structure covered in Data Structures I and II, hash table, BST, AVL/red-black tree, heap, union-find, trie, skip list, and Bloom filter, organized by what each one is actually good at.

    Read →6 sections20 min

Data Structures II

Part of the Computer Science curriculum.

Sort
1

The Birthday Paradox and Collision Probability

Collisions depend on n squared relative to m, not n relative to m, so they become likely once n reaches roughly the square root of m, far earlier than a hash table being anywhere near full.

2

Universal Hashing

No single fixed hash function can resist an adversary who knows it, so universal hashing draws a fresh function at random from a family guaranteeing collision probability at most 1/m for any pair of keys.

3

Perfect Hashing

The FKS two-level construction eliminates collisions entirely, worst-case O(1) lookup with expected O(n) total space, but only for a static set of keys known completely in advance.

4

Bloom Filters: Probabilistic Set Membership

A bit array plus k hash functions, with no keys ever stored, gives false positives that are possible but false negatives that are structurally impossible.

5

False Positive Rate and Optimal Parameters

The false positive rate is approximately (1 - e^(-kn/m))^k, minimized at k = (m/n)*ln(2), shrinking exponentially as more bits per element are allocated, turning filter sizing into simple arithmetic.

6

Tries: Prefix Trees for String Keys

A tree where a key's characters are spelled out one per edge along a root-to-node path — keys sharing a prefix share that prefix's path, something no hash table can offer.

7

Trie Operations: Insert, Search, Prefix-Match

Inserting and searching a trie one character at a time, and the operation a hash table fundamentally cannot do efficiently — listing every key that starts with a given prefix.

8

Ternary Search Tries

A space-efficient trie variant using three children per node instead of one per alphabet character, trading a little search speed for a dramatically smaller memory footprint.

9

Real Applications: Autocomplete and Routing Tables

Two genuine, well-known uses of prefix trees — a search box's autocomplete suggestions, and a router's longest-prefix-match lookup for forwarding IP packets.

10

The Union-Find (Disjoint-Set) ADT

A structure for tracking a collection of disjoint groups, supporting exactly two operations — merge two groups, and ask whether two elements are in the same one.

11

Quick-Find and Quick-Union

Two naive first attempts at implementing union-find — one makes membership-checking instant but merging slow, the other the reverse — neither good enough on its own.

12

Union by Rank and Size

The first key optimization: always attach the smaller (or shallower) tree under the bigger one's root, which alone caps every tree's height at O(log n).

13

Path Compression

The second key optimization: while walking up to find a group's root, point every node visited along the way directly at that root, flattening the tree for every future lookup.

14

Amortized Analysis of Union-Find

Combined, union by rank and path compression make a sequence of operations run in almost — but not quite exactly — constant time each, a famous result involving the inverse Ackermann function.

15

The Heap Property

A binary tree where every node is at least as large as (or at least as small as) both of its children — weaker than a BST's ordering, but exactly enough to make "find the max" instant.

16

Array Representation of a Binary Heap

Storing a complete binary tree in a plain array — a node at index i has children at 2i+1 and 2i+2 — avoiding pointers entirely and packing the tree with zero wasted space.

17

Heap Insert and Extract-Max/Min

The two operations a priority queue actually needs — adding an element and removing the highest (or lowest) priority one — each done in O(log n) by bubbling along a single root-to-leaf path.

18

Heapify: Building a Heap in Linear Time

Turning an arbitrary array into a valid heap in O(n) time, not the O(n log n) a naive one-at-a-time insertion would cost — a genuinely surprising result worth deriving carefully.

19

Heapsort

Heapify the whole array once, then repeatedly extract the max into the back of the array — an O(n log n), in-place sort that falls directly out of the heap operations already covered.

20

Why Balance Matters

Picking up exactly where Data Structures I left off: a plain BST degrades to O(n) on a lopsided tree, and this discipline exists to fix that guarantee for good.

21

AVL Trees: The Balance Invariant

A binary search tree that enforces one simple rule after every insertion or deletion — the heights of any node's two subtrees never differ by more than one.

22

AVL Rotations: Single and Double

The local, constant-time restructuring operation — a rotation — that restores AVL's balance invariant after an insertion or deletion knocks it out of alignment.

23

Red-Black Trees: An Alternative Balance Scheme

A looser balance invariant, enforced with a color on every node instead of a strict height check — the scheme most production libraries (Java's TreeMap, C++'s std::map) actually use.

24

Comparing AVL and Red-Black Trees in Practice

Both guarantee O(log n) operations — the real difference is in the constants: AVL's stricter balance means faster lookups but more rotations; red-black's looser balance means the reverse.

25

Skip Lists: A Probabilistic Alternative to Balance

A hierarchy of sorted linked lists, where an element's height is decided by an independent coin flip at insertion, achieving expected O(log n) with no invariant to maintain and no rotation logic at all.

26

Skip List Search, Insertion, and Deletion

Insertion and deletion reuse the exact same downward search pass, recording an update array of predecessor nodes per level, with no separate fix-up phase of any kind.

27

Skip List Expected Height and Why Randomization Works

An element reaches level k with probability (1/2)^k, giving expected height Θ(log n) and expected O(log n) search, a guarantee over the skip list's own coin flips that no adversarial input can defeat.

28

Choosing a Data Structure: A Decision Guide

A side-by-side decision guide across every structure covered in Data Structures I and II, hash table, BST, AVL/red-black tree, heap, union-find, trie, skip list, and Bloom filter, organized by what each one is actually good at.