Why must a binary tree's preorder serialization include explicit null markers to be decodable?
answer
- the string must pin down shape, not just order
- three different trees, one token sequence
- what makes a subtree's block self-delimiting
- every node owns two child slots
- n nodes leave n+1 empty slots
basics
~20 sWithout markers the token stream records visit order but not which child slots are empty, so many different shapes produce the same sequence. A marker for every empty child makes each node's two slots explicit, and decoding becomes unambiguous.
solid answer
~40 sA preorder walk emits the node, then its left subtree, then its right subtree. With values only, the decoder cannot tell whether the next token is the left child of the node it just read or the right child of some ancestor: the trees `1(left 2(left 3))`, `1(left 2(right 3))` and `1(left 2, right 3)` all emit `1 2 3`. Emitting a marker whenever a child is absent removes the ambiguity, because every node now contributes exactly two child slots to the stream. A tree of n nodes has n+1 empty slots, so the encoding is 2n+1 tokens. The decoder is then a single left-to-right pass: read a token, return empty on a marker, otherwise build the node and recursively fill left then right from the same cursor.
go deeper
Be ready to show two different trees whose value-only preorder is the same sequence, then say what the markers add. Knowing that empty children must be recorded is the whole point of the question.
Explain the decoder as a single cursor pass that consumes exactly its own subtree, and derive the 2n+1 token count from the child-slot argument rather than quoting it.
Talk about the encoding as a wire contract: marker collisions with real keys, delimiters, truncated or over-long streams, and why decoding should fail loudly instead of producing a partial tree.
Own the choice between a compact hand-rolled marker stream and a self-describing format the whole fleet already parses, and say what each costs in size, debuggability and version skew.
## What a serialization actually has to pin down A binary tree is two things at once: a **shape** (which nodes exist and how they hang off each other) and a **labelling** (what key sits at each position). A traversal by itself only reports the labels in a particular visiting order. Reconstruction needs the shape too, and that is exactly the part a bare value sequence throws away. ### The ambiguity, concretely Preorder means: emit the node, then the whole left subtree, then the whole right subtree. Consider three different three-node trees: ``` 1 1 1 / / / \ 2 2 2 3 / \ 3 3 ``` All three emit `1 2 3`. The decoder receiving `1 2 3` has no way to place the `3`: left-left, left-right, and right-of-root are all consistent. The number of distinct shapes on n nodes grows like the Catalan numbers, while there is only one value sequence, so ambiguity is not an edge case — it is the normal situation. ### The marker encoding Fix it by making the *absent* children visible. Serialize recursively: if the node is empty, emit a marker token (often written `#`); otherwise emit the key, then serialize left, then serialize right. The same three trees now separate cleanly: ``` 1 2 3 # # # # (left-left chain) 1 2 # 3 # # # (left, then its right child) 1 2 # # 3 # # (two children of the root) ``` **Why the length is 2n+1.** Every node owns two child slots, so a tree of n nodes has 2n slots. Every node except the root fills exactly one slot, so n-1 slots are filled and 2n-(n-1) = n+1 are empty. The stream carries n keys plus n+1 markers. ### Why decoding is one pass The decoder never has to scan ahead to find where the left subtree ends. It keeps a cursor over the token stream and calls itself: ``` build(): t = next token if t == marker: return empty node = new node with key t node.left = build() node.right = build() return node ``` Each recursive call consumes exactly the block of tokens belonging to its own subtree, because a subtree's encoding is self-delimiting: it ends precisely when both of its children's calls have returned. Time is O(n), auxiliary space is O(h) for the recursion stack, where h is the height — O(n) for a degenerate chain, O(log n) for a balanced tree. Recursion depth is real space, so a deep tree may need an explicit stack instead. ### The alternatives, and what each costs - **Level-order with markers.** Same idea driven by a queue instead of recursion; also unambiguous, and often nicer to read for a shallow wide tree. Trailing markers can be trimmed. - **Two traversals instead of markers.** Preorder plus inorder reconstructs a binary tree *if every key is distinct*; so does inorder plus postorder. Preorder plus postorder does **not** — a node with exactly one child looks identical either way, so that pair is unique only for trees where every node has zero or two children. Duplicate keys break all of these pairings, which is one reason the marker form is the safer default. - **Inorder alone.** Useless for reconstruction: for a search tree it is just the sorted key list, which is consistent with every possible shape over those keys. ### Practical traps The marker must be a token that no real key can equal, otherwise a key that happens to look like the marker silently truncates a subtree. Either escape values, or use a delimited/typed encoding where a marker is a distinct token type rather than a magic string. Delimiters matter too: without them, keys `1` and `2` concatenate into something that also reads as `12`. Finally, decode defensively — a truncated stream leaves the recursion asking for tokens that do not exist, and a stream with extra trailing tokens means the sender and receiver disagree about the encoding, both of which should be errors rather than a half-built tree.
- How many tokens does the marker encoding emit for a tree of n nodes, and why exactly that many?2n+1. Each of the n nodes owns two child slots, giving 2n slots in total; every node except the root fills exactly one, so n-1 are filled and n+1 stay empty. The stream is therefore n keys plus n+1 markers, regardless of shape.
- Can two traversals replace the markers, and is there a pair that fails?Preorder plus inorder, or inorder plus postorder, reconstruct a binary tree when all keys are distinct. Preorder plus postorder fails: a node with exactly one child produces the same pair whether that child is on the left or the right, so it is unique only when every node has zero or two children. Duplicate keys defeat all of these pairings.
- What breaks if a stored key can equal the marker token?The decoder reads that key as an empty child and stops descending, so it silently builds a smaller, wrong tree instead of reporting an error. Fix it by escaping key values, by tagging tokens with a type so a marker is not a value at all, or by length-prefixing so the parser never has to guess.
A value-only traversal is like a nested outline typed without indentation: the headings are all there in order, but you can no longer tell which one belongs under which.
saying these in an interview costs you the question
- Claims a preorder sequence uniquely determines the tree
- Says inorder alone is enough to rebuild the shape
- Picks a marker token that a real key can equal
- Thinks the decoder must scan ahead to split subtrees
- Calls the markers wasted bytes with no benefit