Binary Strings as Paths in a Tree
A binary code assigns finite strings of 0s and 1s to symbols. When no codeword is the beginning of another, a decoder can identify a codeword as soon as its final bit is read. Rooted binary trees make this structure visible: a 0 or 1 records which child is taken, and a codeword is the path from the root to a leaf. The depth of that leaf is the codeword's length, so frequencies can be used to calculate the total number of bits required.
A binary string is a finite sequence of bits. The empty string, denoted \(\varepsilon\), has length \(0\). For strings \(x\) and \(y\), \(x\) is a prefix of \(y\) if \(y\) begins with all the bits of \(x\); the string is a proper prefix if, in addition, \(x\ne y\). A set \(C\) of distinct binary strings is prefix-free if no member of \(C\) is a proper prefix of another member.
A tree can have vertices with just one child; it need not be a full binary tree. A codeword of length \(k\) labels a leaf at depth \(k\), where depth is the number of edges from the root. The set containing only \(\varepsilon\) is prefix-free and is represented by a tree consisting of a single root, which is also its leaf. The empty set is prefix-free as well, but it cannot label the leaves of a nonempty rooted tree. In the characterization below, the code set is therefore required to be nonempty. One could represent the empty set by separately allowing an empty tree, but that convention is not used here.
The Tree Characterization
Proof. First suppose \(C\) is prefix-free. Take as vertices all prefixes of strings in \(C\), including \(\varepsilon\). Join each nonempty prefix \(x\) to the prefix obtained by deleting its last bit; label that edge by the deleted bit. The resulting graph is connected: repeatedly deleting the last bit takes any vertex to \(\varepsilon\). It has no cycle, since each nonroot vertex has exactly one parent and repeatedly following parents strictly decreases string length until reaching the root. Thus it is a rooted tree. At each vertex there is at most one child labeled 0 and at most one child labeled 1, so it is binary.
Every string \(c\in C\) is a vertex. It is a leaf: if it had a child, then some string in \(C\) would have \(c\) as a proper prefix, contrary to prefix-freeness. Conversely, any leaf is in \(C\). Indeed, every vertex was included because it is a prefix of some \(c\in C\); if a leaf \(x\) were a proper prefix of \(c\), the next bit of \(c\) would give \(x\) a child. Therefore the leaves are exactly the strings in \(C\). This also covers \(C=\{\varepsilon\}\): the only prefix is the root, and it is a leaf.
Now suppose a finite rooted binary tree represents \(C\), with each codeword labeling a leaf. If two distinct leaf path labels \(x\) and \(y\) had \(x\) as a proper prefix of \(y\), then the path for \(y\) would continue past the vertex reached by the path for \(x\). That vertex would have a child, so it would not be a leaf. This contradicts the assumption that \(x\) labels a leaf. Thus no codeword is a proper prefix of another, and \(C\) is prefix-free. \(\square\)
Worked Example: Building a Tree for Three Codewords
Assign codewords \(0,10,11\) to symbols \(A,B,C\), respectively. The set \(C=\{0,10,11\}\) is prefix-free: \(0\) is not a prefix of \(10\) or \(11\), and \(10\) and \(11\) have the same length and are distinct.
The tree has vertex set \(V=\{\varepsilon,0,1,10,11\}\) and edge set \(E=\{\varepsilon0,\varepsilon1,1\,10,1\,11\}\), with each edge labeled by the bit added in moving from parent to child. Its leaves are \(0,10,11\): vertex \(0\) has no child, and vertex \(1\) has the two children \(10\) and \(11\). The root-to-leaf paths therefore give exactly the assigned codewords.
Check: The codeword lengths are \(|0|=1\), \(|10|=2\), and \(|11|=2\). Each length equals the number of edges on its corresponding root-to-leaf path: one edge to \(0\), and two edges to either \(10\) or \(11\).
Unique Decoding and the Empty Codeword
Prefix-freeness ensures unique parsing when all codewords are nonempty. Nonemptiness matters: if \(\varepsilon\) is a codeword, then it can be repeated any number of times without changing the concatenated string. For instance, the singleton set \(\{\varepsilon\}\) is prefix-free, but the empty bit string can be parsed as zero copies, one copy, two copies, or any number of copies of its codeword.
Proof. Existence of a parsing is part of the hypothesis that the bit string is a concatenation of codewords. To prove uniqueness, let a string \(w\) have two parsings. If \(w=\varepsilon\), no nonempty codeword can occur in either parsing, so both are the empty sequence of codewords. Now suppose \(w\ne\varepsilon\). Let \(x\) and \(y\) be the first codewords in the two parsings. Each is an initial segment of \(w\), so the shorter one is a prefix of the longer one. Since \(C\) is prefix-free, they cannot be distinct; therefore \(x=y\). Remove this common, nonempty initial segment from \(w\). The two remaining sequences parse the same suffix, whose length is strictly less than the length of \(w\). Induction on the length of \(w\), with the empty string as the base case, shows that the remaining parsings agree. Thus the original parsings agree, and because different symbols have different codewords, their symbol sequences agree as well. \(\square\)
This result concerns parsing strings that are concatenations of codewords; it does not claim that every possible binary string can be parsed. A string that ends partway through a codeword, for example, need not have any parsing. Also, the tree representation theorem permits \(\varepsilon\) in a prefix-free set, whereas the unique-decoding theorem above deliberately excludes it.
Worked Example: A Prefix-Free Code with Unique Parsing
Let \(C=\{0,10,11\}\), with \(A\) assigned \(0\), \(B\) assigned \(10\), and \(C\) assigned \(11\). Parse the bit string \(01011\) from left to right. Its first bit is \(0\), a codeword, so the first symbol is \(A\). The remaining string is \(1011\). Its first two bits are \(10\), a codeword, leaving \(11\), which is also a codeword. The parsing is therefore \(0\,|\,10\,|\,11\), giving the symbol sequence \(ABC\).
Check: Concatenating those codewords gives \(0\,10\,11=01011\), the original string. The initial codeword is forced: \(0\) is a codeword, while neither \(10\) nor \(11\) begins with \(0\). After removing it, the next codeword is forced by prefix-freeness in the same way. The theorem guarantees that no different parsing gives the same bit string.
Weighted Path Lengths
Suppose symbol \(i\) occurs \(f_i\) times in a data source and is assigned codeword \(c_i\). The weighted path length of the code is the total number of bits used when encoding those occurrences:
If the total number of symbol occurrences is \(F=\sum_i f_i>0\), the average number of bits per symbol is \(L/F\). Equivalently, if \(p_i=f_i/F\) is the proportion of occurrences of symbol \(i\), then the average length is \(\sum_i p_i|c_i|\). The tree gives a direct way to compute these quantities: \(|c_i|\) is the depth of the leaf for symbol \(i\). The formula measures the cost of a specified code; it does not by itself find a code with minimum cost.
Worked Example: Calculating a Weighted Path Length
Use the code tree with vertex set \(V=\{\varepsilon,0,1,10,11\}\) and edge set \(E=\{\varepsilon0,\varepsilon1,1\,10,1\,11\}\). Assign \(0\) to \(A\), \(10\) to \(B\), and \(11\) to \(C\), with frequencies \(f_A=5\), \(f_B=2\), and \(f_C=3\). The corresponding depths are \(|0|=1\), \(|10|=2\), and \(|11|=2\).
Substituting into the formula gives \(L=5\cdot1+2\cdot2+3\cdot2=5+4+6=15\) bits. There are \(F=5+2+3=10\) symbols, so the average length is \(L/F=15/10=1.5\) bits per symbol.
Check: Count by depth instead. The frequency at depth 1 is \(5\), contributing \(5\cdot1=5\) bits. The total frequency at depth 2 is \(2+3=5\), contributing \(5\cdot2=10\) bits. Thus \(5+10=15\) bits, agreeing with the symbol-by-symbol calculation; dividing by \(10\) again gives \(1.5\) bits per symbol.
Worked Example: A Complete Two-Level Code
Let symbols \(A,B,C,D\) have codewords \(00,01,10,11\), respectively. The tree has vertex set \(V=\{\varepsilon,0,1,00,01,10,11\}\) and edge set \(E=\{\varepsilon0,\varepsilon1,0\,00,0\,01,1\,10,1\,11\}\). Its four leaves are the four codewords, all at depth 2. Assign frequencies \(f_A=8\), \(f_B=4\), \(f_C=3\), and \(f_D=1\).
The total frequency is \(F=8+4+3+1=16\). Each symbol uses two bits, so the weighted path length is \(L=8\cdot2+4\cdot2+3\cdot2+1\cdot2=16+8+6+2=32\) bits. The average length is \(32/16=2\) bits per symbol.
Check: Since all \(16\) occurrences use exactly \(2\) bits, counting by occurrences gives \(16\cdot2=32\) bits, the same total. The assigned codewords are distinct and all have equal length, so none is a prefix of another.
Worked Example: Unequal Leaf Depths
Take the codewords \(0,100,1010,1011\), assigned to \(A,B,C,D\), respectively. The tree has vertex set \(V=\{\varepsilon,0,1,10,100,101,1010,1011\}\) and edge set \(E=\{\varepsilon0,\varepsilon1,1\,10,10\,100,10\,101,101\,1010,101\,1011\}\). Its leaves are \(0,100,1010,1011\), at depths \(1,3,4,4\). Assign frequencies \(f_A=7\), \(f_B=2\), \(f_C=4\), and \(f_D=1\).
The weighted path length is \(L=7\cdot1+2\cdot3+4\cdot4+1\cdot4=7+6+16+4=33\) bits. The total frequency is \(F=7+2+4+1=14\), so the average length is \(33/14\) bits per symbol.
Check: Grouping by depth gives \(7\) occurrences at depth 1, \(2\) at depth 3, and \(4+1=5\) at depth 4. The total is \(7\cdot1+2\cdot3+5\cdot4=7+6+20=33\) bits. The leaves have different depths, and their lengths match the numbers of edges in the stated tree.
A Common Prefix Mistake
A codeword cannot be a leaf if another codeword extends it. For example, the set \(\{0,01\}\) is not prefix-free, because \(0\) is a proper prefix of \(01\). Its prefix tree has vertices \(V=\{\varepsilon,0,01\}\) and edges \(E=\{\varepsilon0,0\,01\}\). The path labeled \(0\) ends at an internal vertex, not at a leaf; the only leaf path label is \(01\). So this tree does not represent both proposed strings as leaf codewords.
A tempting but incorrect calculation is to treat both strings as leaves and assign them lengths \(1\) and \(2\). With frequencies \(f_0=3\) and \(f_{01}=2\), that gives the apparent weighted length \(3\cdot1+2\cdot2=7\). The calculation uses the wrong tree structure: the two proposed codewords are not prefix-free and cannot both label leaves. One prefix-free repair is to replace \(0\) by \(00\). The set \(\{00,01\}\) has tree \(V=\{\varepsilon,0,00,01\}\), \(E=\{\varepsilon0,0\,00,0\,01\}\), and both codewords label leaves. If the frequencies remain \(3\) and \(2\), the repaired assignment has weighted length \(3\cdot2+2\cdot2=10\) bits. The correction changes the code, so its cost must be recalculated from its actual leaf depths.
Tree depth is useful because it turns code length into a visible path measurement, and the weighted sum makes the effect of different symbol frequencies explicit. Prefix-freeness gives both the leaf structure and unambiguous decoding when codewords are nonempty. Finding an optimal prefix code from frequencies is a separate problem; the greedy construction and its proof are treated in the later material on the Huffman algorithm.
Check Your Understanding
Use the definitions and results above to answer these questions.
- Why is the empty set prefix-free, yet not representable by the leaves of a nonempty rooted tree under the stated convention?
- Construct the prefix tree for \(\{00,01,10\}\). Give its vertex and edge sets, and identify its leaves.
- Explain why \(\{\varepsilon\}\) is prefix-free but does not satisfy the unique-decoding theorem.
- For codewords \(0,10,11\) with frequencies \(4,1,5\), calculate the weighted path length and average length.
- Give a concrete example showing why two strings one of which is a proper prefix of the other cannot both label leaves of the same tree.