A bijection between labelled trees on vertices and sequences of length over . It gives an immediate proof of Cayley’s formula and a clean way to sample or count trees with degree constraints.
Encoding
Repeat times: find the leaf with the smallest label, append its neighbour to the code, and delete the leaf.
1 - 3 - 2 code: leaf 1 -> append 3
| then leaf 2 -> append 3 (or as the process dictates)
4
Naive is ; with a pointer that only ever moves forward it becomes :
vector<int> pruferEncode(int n, vector<int>& par) { // tree rooted at n-1
vector<int> deg(n, 1);
for (int i = 0; i < n - 1; i++) deg[par[i]]++;
vector<int> code;
int ptr = 0;
while (deg[ptr] != 1) ptr++;
int leaf = ptr;
for (int i = 0; i < n - 2; i++) {
int nxt = par[leaf];
code.push_back(nxt);
if (--deg[nxt] == 1 && nxt < ptr) leaf = nxt; // new small leaf appeared
else { while (deg[++ptr] != 1); leaf = ptr; }
}
return code;
}Decoding
Compute each vertex’s degree as (its count in the code) . Then repeatedly take the smallest-labelled vertex of degree 1, join it to the next code entry, and decrement both degrees. The two vertices left at the end are joined.
Consequences
| Result | Why |
|---|---|
| Cayley’s formula: labelled trees on vertices | the code is an arbitrary sequence of length over symbols |
| Vertex appears times in the code | it is removed from the tree only when it becomes a leaf |
| Trees with prescribed degrees | multinomial |
| Forests with trees and specified roots | (generalised Cayley) |
| Spanning trees of | |
| Labelled trees where vertex is a leaf |
The degree fact is the workhorse: any question of the form “count labelled trees where vertex has degree constraint ” becomes a counting problem over sequences, which is usually a multinomial or a small DP.
Uniform random tree generation
Generate uniformly random labels and decode. This samples a labelled tree uniformly at random in — far better than the “add random edges and check acyclicity” approach, which is biased and slow.
vector<int> randomTree(int n) {
vector<int> code(n - 2);
for (auto& x : code) x = rng() % n;
return pruferDecode(n, code);
}This is the standard way to generate tree test cases for stress testing.
Related counting results
- Matrix-Tree theorem — counts spanning trees of an arbitrary graph as a determinant. Prüfer handles only complete graphs, but does so bijectively and constructively.
- Wilson’s algorithm — samples a uniform random spanning tree of any graph via loop-erased random walks.
- Kirchhoff’s theorem — the undirected Matrix-Tree statement.
A caution
Prüfer codes apply to labelled trees. Counting unlabelled (isomorphism classes of) trees is a much harder problem with no closed form — the counts are OEIS A000055, computed by Pólya enumeration. Do not use when the problem says “shapes”.
See also: Combinatorics · Matrix-Tree Theorem · Tree Fundamentals