Graphs/Eulerian Tours

Lesson 6.91,543 words

Eulerian Tours

An Eulerian tour uses every edge of a graph exactly once. We give the exact parity and balance conditions under which one exists (even degree for undirected graphs, in-degree equal to out-degree for directed) and Hierholzer's O(E)O(E) algorithm that constructs one by splicing closed sub-tours.

╌╌╌╌

The traversals of the previous lessons were about reaching vertices: BFS and DFS each touch every vertex once and impose no constraint on how often an edge is used. This lesson turns the question inside out. We ask for a walk that crosses every edge exactly once: the problem Euler posed in 1736 for the seven bridges of Königsberg, and the historical seed of graph theory itself. Unlike most use everything exactly once problems, this one has a clean local characterization and a linear-time algorithm.

It is worth fixing the contrast that gives the lesson its shape. An Eulerian tour constrains edges; its near-twin, the Hamiltonian tour, constrains vertices, visiting every vertex exactly once. The two look like mirror images, but they sit on opposite sides of the great divide in algorithms. Deciding whether an Eulerian tour exists, and building one, takes time, as we will see. Deciding whether a Hamiltonian cycle exists is NP-complete: no polynomial algorithm is known, and finding one would settle vs (we return to intractability in a later module).1 The slogan to remember: visiting every edge is easy; visiting every vertex is hard.

When does an Eulerian tour exist?

The existence test is pure local arithmetic on degrees. The intuition is a single parity argument: think of walking through the tour and watching one fixed vertex . Every time the walk passes through it arrives on one edge and leaves on another, consuming a pair of edges incident to . So the edges at an interior vertex must come in pairs.

For directed graphs the parity condition sharpens into a balance condition, because each edge now has a direction: a through-passage at consumes one incoming and one outgoing edge.

The two extra-edge vertices are forced: a start emits one more edge than it absorbs, an end absorbs one more than it emits, and everyone the walk merely passes through breaks even. Connectivity is the second, easily-forgotten half of the test: degrees can balance perfectly while the edges split into two disjoint loops, which no single walk can join.

directed path: start has , end has , balanced
balanced but disconnected: two separate even loops admit no single Eulerian tour
Eulerian path 0 or 2 odd-degree vertices

Here and each have odd degree ; the other two are even, so an Eulerian path exists and must run between and . The numbering is one valid traversal , which crosses all five edges once and stops at .

Hierholzer's algorithm

The natural greedy idea is almost right: start somewhere, keep walking along edges you have not used, and never look back. Because every vertex is balanced (or you begin at an odd endpoint), you can always leave a vertex you entered, so the walk only ever gets stuck back at its starting vertex, closing a loop. But that first loop may not have swallowed every edge. Hierholzer's algorithm fixes this with one elegant move: whenever a vertex on the current tour still has unused edges hanging off it, splice a fresh closed sub-tour in at that vertex, and repeat until nothing is left over.

merge closed sub-tours into one Eulerian circuit

The blue loop is a closed sub-tour discovered when the main walk reached and found unused edges. Inserting it at yields the single circuit .

The clean implementation does the splicing implicitly with a stack and one edge pointer per vertex (so each vertex resumes scanning where it left off, never re-examining a used edge). We push our way forward along unused edges; when a vertex runs dry, we pop it onto the output. The route is therefore emitted in reverse on backtracking, and a spliced sub-tour is naturally inserted at its shared vertex.

Algorithm:Hierholzer(G,s)\textsc{Hierholzer}(G, s) — build an Eulerian tour from start ss in O(E)O(E)
  1. 1
    for each vertex vv do
  2. 2
    ptr[v]0ptr[v] \gets 0
    next-unused-edge index
  3. 3
    stack[s]stack \gets [\,s\,];\ \ \ route[]route \gets [\,]
  4. 4
    while stackstack is nonempty do
  5. 5
    ustack.top()u \gets stack.\text{top}()
  6. 6
    if ptr[u]<adj[u]ptr[u] < |adj[u]| then
    u has an unused edge
  7. 7
    wadj[u][ptr[u]]w \gets adj[u][\,ptr[u]\,]
  8. 8
    ptr[u]ptr[u]+1ptr[u] \gets ptr[u] + 1
    consume edge u→w
  9. 9
    stack.push(w)stack.\text{push}(w)
    walk forward
  10. 10
    else
    u exhausted: back out
  11. 11
    route.append(stack.pop())route.\text{append}(stack.\text{pop}())
  12. 12
    return reverse(route)\textbf{return } reverse(route)
    emitted in reverse on backtrack

Why it consumes every edge. Each iteration either advances an edge pointer (consuming exactly one edge) or pops one vertex; both can happen at most and times respectively, so the loop runs in on a connected graph. The pointer trick means each edge is examined once, never rescanned. When a vertex is finally popped, the algorithm has, by the parity argument, already drained every edge incident to along the way; any edge it had skipped would have been picked up by a later pointer advance before could exhaust. Reading in reverse threads every discovered sub-tour through its splice vertex, producing one walk that uses all edges exactly once. If the existence conditions hold, the output is a valid Eulerian tour; for an open Eulerian path, start at the unique out-excess vertex (directed) or an odd-degree vertex (undirected).3

Applications

The pattern use every edge once is more common than it first appears. Reconstruct Itinerary asks for a flight schedule that uses every ticket exactly once: an Eulerian path on the directed multigraph of airports, where the problem's lexicographically-smallest requirement is met by keeping each vertex's outgoing destinations in sorted order and letting Hierholzer consume them in that order. De Bruijn sequences are the gem: to find a shortest cyclic string containing every length- string over an alphabet exactly once (the Cracking the Safe problem), build the de Bruijn graph whose vertices are -grams and whose edges are -grams; that graph is balanced by construction, so an Eulerian circuit spells out the optimal sequence.

The smallest case makes it vivid. For binary strings of length , the de Bruijn graph has two vertices, the -grams and , and four edges, the -grams . Every vertex is balanced (in-degree out-degree ), so an Eulerian circuit exists; following and reading the new symbol off each edge spells the de Bruijn sequence , a length- cyclic string in which all four -bit patterns appear exactly once:

The binary de Bruijn graph (vertices ; edges = the four -grams). Its Eulerian circuit spells the cyclic de Bruijn sequence .

The same idea drives DNA fragment assembly, where overlapping reads become edges of a de Bruijn graph and an Eulerian path stitches the genome back together, a problem that, posed instead as a Hamiltonian path over the reads, would be hopeless.

Takeaways

  • An Eulerian path uses every edge exactly once; an Eulerian circuit is a closed one. This is the easy cousin of the Hamiltonian tour (every vertex once), which is NP-complete — edges are easy, vertices are hard.
  • Undirected existence: a connected graph has an Eulerian circuit iff every vertex has even degree, and an Eulerian path iff exactly or vertices have odd degree (the two odds are the endpoints). The parity argument: each through-visit consumes a pair of incident edges.
  • Directed existence: an Eulerian circuit iff everywhere; an Eulerian path iff one vertex has (start), one has (end), rest balanced — plus connectivity of the edge set.
  • Hierholzer's algorithm builds a tour in by walking until it closes a sub-tour, then splicing in further closed sub-tours at vertices with leftover edges; a stack plus a per-vertex edge pointer emits the route in reverse on backtrack.
  • Applications: itinerary reconstruction (lexicographic via sorted edges), de Bruijn sequences (Eulerian circuit on the de Bruijn graph), and DNA fragment assembly.

Footnotes

  1. Erickson, Ch. — Graph Traversal: Eulerian tours via the degree characterization, contrasted with the NP-complete Hamiltonian problem.
  2. Skiena, § — Eulerian Cycles: the even-degree (balanced) existence condition and its parity proof.
  3. CLRS, Ch. — Euler Tour (Problem): linear-time construction of an Eulerian tour on a graph satisfying the degree/balance conditions.
Practice

╌╌ END ╌╌