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

ResultWhy
Cayley’s formula: labelled trees on verticesthe code is an arbitrary sequence of length over symbols
Vertex appears times in the codeit 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.

  • 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