The arc closes
Lesson 11's first drill showed a trap: save the tree via Keys(), reload by
inserting key after key, and you get a list — because Keys() returns a sorted
list.
The question asks itself: is that safe now?
$ algo reload -in s10k.jsonl
original: BST height 30, AVL height 16
reloaded from Keys(): BST height 10000, AVL height 14
AVL rotations during that reload: 9986 (0.999 per insert)
Yes. And not merely safe — the tree comes back better than it went in. 16 → 14.
The reason is already known from step 1: sorted input is the AVL tree's best case. A naive save hands it exactly that.
The same line gives the BST 10,000.
In lesson 11 the save format was a correctness question. In lesson 12 it went back to being just a format.
That is what the guarantee actually buys. Not speed — a whole class of bug removed from the set of things you have to think about. You no longer have to ask what order the keys arrive in, because the answer stopped mattering.
Three structures, one question
Since lesson 10 you have built three indexes for the same library. All three measured on the same 10,000 records:
| hash (10) | BST (11) | AVL (12) | |
|---|---|---|---|
| exact-key lookup | 1.310 comparisons | 16.703 | 12.540 |
the same, -sorted input |
1.310 | 5000.5 | 12.363 |
| sorted listing | impossible without a full sort | a walk | a walk |
range, Min, Max, neighbours |
not a concept it has | yes | yes |
| build (shuffled) | fastest | 1.80–1.94 ms | 2.82–3.35 ms |
| what it promises | O(1) on average | O(log n) on average | O(log n) in the worst case |
And this is not a ladder
It is easy to read that table as "12 is the best one". It is not.
Lesson 10 wins. If your program only needs "is this key present" — a session store, word frequencies, "is this username taken" — the hash table is 9.6× cheaper than the AVL tree and you need none of the other operations. Building a tree there would be a mistake, not caution.
Every structure sold something:
| lesson | what it bought | what it paid with |
|---|---|---|
| 10 | O(1) exact-key lookup | all order — no ranges, no neighbours, no listing |
| 11 | order and every operation that comes with it | the guarantee — insertion order decides everything |
| 12 | the guarantee back | the constant — insertion 1.65× slower |
Three rows, three trades. None of the structures is "better" — they answer different questions, and the question lesson 10 asked has not changed since.
What you actually learned
Not three data structures. How the choice is made.
In each of the three lessons the route was the same:
- ask a specific question about the data;
- measure what each structure charges for it — in comparisons, not in intuition;
- name what it cannot do, not only what it does slowly;
- ask whether your worst case is merely unpleasant or unacceptable.
The fourth point is this lesson's contribution. Lesson 11's tree was fine on
shuffled input — right up until the day somebody imported the data
ORDER BY title.
The difference between "usually" and "always" costs 1.65×. Whether it is worth it is no longer a question about algorithms — it is a question about your program.