Fleury's Algorithm for printing Eulerian Path or Circuit (original) (raw)

Last Updated : 23 Jul, 2025

Given an **undirected connected graph with **v nodes, and **e edges, with adjacency list **adj. The task is to print an Eulerian trail or circuit using Fleury's Algorithm

A graph is said to be Eulerian if it contains an **Eulerian Cycle, a cycle that visits every edge exactly once and starts and ends at the same vertex.
If a graph contains an **Eulerian Path, a path that visits every edge exactly once but starts and ends at different vertices

**Examples:

**Input:

Euler1

**Output: 4-3, 3-0, 0-1, 1-2, 2-0

**Input:

Euler2

**Output: 2-1, 1-0, 0-3, 3-4, 4-0, 0-2

**Input:

Euler3

**Output: 0

Before diving into this approach, it's highly recommended to explore this comprehensive article on Eulerian Path and Circuit. Please refer to this Link: **Eulerian path and circuit for undirected graph
The article clearly explains the fundamentals and conditions for identifying whether a graph contains an Eulerian Path or Eulerian Circuit, laying a strong foundation for the solution we’re about to implement.

Approach:

The idea is to use **Fleury’s Algorithm to print an **Eulerian Path or **Eulerian Circuit from a graph by carefully selecting edges during traversal. Here's how the algorithm works:

This approach ensures that the path remains valid and no part of the graph becomes unreachable prematurely.

The idea is, ****"don't burn** **bridges****"** so that we can come back to a vertex and traverse the remaining edges.
For example, let us consider the following graph.

Euler1

There are two vertices with odd degrees, '2' and '3', and we can start paths from any of them. Let us start the tour from vertex '2'.

Euler2

Three edges are going out from vertex '2', which one to pick? We don't pick the edge '2-3' because that is a bridge (we won't be able to come back to '3'). We can pick any of the remaining two edges. Let us say we pick '2-0'. We remove this edge and move to vertex '0'.

Eule3

There is only one edge from vertex '0', so we pick it, remove it and move to vertex '1'. Euler tour becomes '2-0 0-1'.

Euler4

There is only one edge from vertex '1', so we pick it, remove it and move to vertex '2'. Euler tour becomes '2-0 0-1 1-2'

Euler5

Again there is only one edge from vertex 2, so we pick it, remove it and move to vertex 3. Euler tour becomes '2-0 0-1 1-2 2-3'

Euler6

There are no more edges left, so we stop here. Final tour is '2-0 0-1 1-2 2-3'.

Once an edge is processed (included in the Euler tour), we remove it from the graph. To remove the edge, we replace the vertex entry with -1 in the adjacency list. Note that simply deleting the node may not work as the code is recursive and a parent call may be in the middle of the adjacency list.

C++ `

// C++ program to print Eulerian Path or // Circuit using Fleury’s Algorithm #include <bits/stdc++.h> using namespace std;

// Function to remove edge u-v from the graph void removeEdge(vector adj[], int u, int v) { adj[u].erase(find(adj[u].begin(), adj[u].end(), v)); adj[v].erase(find(adj[v].begin(), adj[v].end(), u)); }

// DFS to count reachable vertices from v void dfsCount(int v, vector adj[], vector &visited) { visited[v] = true;

for (int neighbor : adj[v]) {
    if (!visited[neighbor]) {
        dfsCount(neighbor, adj, visited);
    }
}

}

// Check if edge u-v is a valid next edge to traverse bool isValidNextEdge(int u, int v, vector adj[], int totalV) {

if (adj[u].size() == 1) {
    return true;
}

vector<bool> visited(totalV, false);
int count1 = 0;
dfsCount(u, adj, visited);
for (bool x : visited) {
    if (x) {
        count1++;
    }
}

removeEdge(adj, u, v);

fill(visited.begin(), visited.end(), false);
int count2 = 0;
dfsCount(u, adj, visited);
for (bool x : visited) {
    if (x) {
        count2++;
    }
}

adj[u].push_back(v);
adj[v].push_back(u);

return count1 == count2;

}

// Recursively collect the Eulerian // path/circuit starting from u void getEulerUtil(int u, vector adj[], vector<vector> &edges, int v) {

for (int i = 0; i < adj[u].size(); ++i) {
    int next = adj[u][i];
    if (isValidNextEdge(u, next, adj, v)) {
        edges.push_back({u, next});
        removeEdge(adj, u, next);
        getEulerUtil(next, adj, edges, v);
        break;
    }
}

}

// Function to return Eulerian trail or circuit vector<vector> getEulerTour(int v, vector adj[]) { int start = 0;

// Find a vertex with odd degree if exists
for (int i = 0; i < v; i++) {
    if (adj[i].size() % 2 != 0) {
        start = i;
        break;
    }
}

vector<vector<int>> edges;
getEulerUtil(start, adj, edges, v);
return edges;

}

// Driver code int main() { int v = 5; vector adj[5] = {{1, 2}, {0, 2}, {0, 1, 3}, {2}};

vector<vector<int>> res = getEulerTour(v, adj);

for (int i = 0; i < res.size(); i++) {
    cout << res[i][0] << "-" << res[i][1];
    if (i != res.size() - 1) {
        cout << ", ";
    }
}

return 0;

}

Java

// Java program to print Eulerian Path or // Circuit using Fleury’s Algorithm import java.util.*;

class GfG {

// Function to remove edge u-v from the graph
static void removeEdge(List<Integer>[] adj, int u, int v) {
    adj[u].remove(Integer.valueOf(v));
    adj[v].remove(Integer.valueOf(u));
}

// DFS to count reachable vertices from v
static void dfsCount(int v, List<Integer>[] adj, 
                     boolean[] visited) {
    visited[v] = true;

    for (int neighbor : adj[v]) {
        if (!visited[neighbor]) {
            dfsCount(neighbor, adj, visited);
        }
    }
}

// Check if edge u-v is a valid next edge to traverse
static boolean isValidNextEdge(int u, int v, 
                               List<Integer>[] adj, int totalV) {

    if (adj[u].size() == 1) {
        return true;
    }

    boolean[] visited = new boolean[totalV];
    int count1 = 0;
    dfsCount(u, adj, visited);
    for (boolean x : visited) {
        if (x) {
            count1++;
        }
    }

    removeEdge(adj, u, v);

    Arrays.fill(visited, false);
    int count2 = 0;
    dfsCount(u, adj, visited);
    for (boolean x : visited) {
        if (x) {
            count2++;
        }
    }

    adj[u].add(v);
    adj[v].add(u);

    return count1 == count2;
}

// Recursively collect the Eulerian 
// path/circuit starting from u
static void getEulerUtil(int u, List<Integer>[] adj, 
                         List<int[]> edges, int v) {

    for (int i = 0; i < adj[u].size(); ++i) {
        int next = adj[u].get(i);
        if (isValidNextEdge(u, next, adj, v)) {
            edges.add(new int[]{u, next});
            removeEdge(adj, u, next);
            getEulerUtil(next, adj, edges, v);
            break;
        }
    }
}

// Function to return Eulerian trail or circuit
static List<int[]> getEulerTour(int v, List<Integer>[] adj) {
    int start = 0;

    // Find a vertex with odd degree if exists
    for (int i = 0; i < v; i++) {
        if (adj[i].size() % 2 != 0) {
            start = i;
            break;
        }
    }

    List<int[]> edges = new ArrayList<>();
    getEulerUtil(start, adj, edges, v);
    return edges;
}

public static void main(String[] args) {
    int v = 4;
    List<Integer>[] adj = new ArrayList[4];
    for (int i = 0; i < 4; i++) {
        adj[i] = new ArrayList<>();
    }
    adj[0].add(1); adj[0].add(2);
    adj[1].add(0); adj[1].add(2);
    adj[2].add(0); adj[2].add(1); adj[2].add(3);
    adj[3].add(2);

    List<int[]> res = getEulerTour(v, adj);

    for (int i = 0; i < res.size(); i++) {
        System.out.print(res.get(i)[0] + "-" + res.get(i)[1]);
        if (i != res.size() - 1) {
            System.out.print(", ");
        }
    }
}

}

Python

Python program to print Eulerian Path or

Circuit using Fleury’s Algorithm

Function to remove edge u-v from the graph

def removeEdge(adj, u, v): adj[u].remove(v) adj[v].remove(u)

DFS to count reachable vertices from v

def dfsCount(v, adj, visited): visited[v] = True

for neighbor in adj[v]:
    if not visited[neighbor]:
        dfsCount(neighbor, adj, visited)

Check if edge u-v is a valid next edge to traverse

def isValidNextEdge(u, v, adj, totalV): if len(adj[u]) == 1: return True

visited = [False] * totalV
count1 = 0
dfsCount(u, adj, visited)
count1 = sum(visited)

removeEdge(adj, u, v)

visited = [False] * totalV
count2 = 0
dfsCount(u, adj, visited)
count2 = sum(visited)

adj[u].append(v)
adj[v].append(u)

return count1 == count2

Recursively collect the Eulerian

path/circuit starting from u

def getEulerUtil(u, adj, edges, v): for i in range(len(adj[u])): next = adj[u][i] if isValidNextEdge(u, next, adj, v): edges.append([u, next]) removeEdge(adj, u, next) getEulerUtil(next, adj, edges, v) break

Function to return Eulerian trail or circuit

def getEulerTour(v, adj): start = 0

# Find a vertex with odd degree if exists
for i in range(v):
    if len(adj[i]) % 2 != 0:
        start = i
        break

edges = []
getEulerUtil(start, adj, edges, v)
return edges

if name == "main": v = 4 adj = [[1, 2], [0, 2], [0, 1, 3], [2]]

res = getEulerTour(v, adj)

for i in range(len(res)):
    print(f"{res[i][0]}-{res[i][1]}", end="")
    if i != len(res) - 1:
        print(", ", end="")

C#

// C# program to print Eulerian Path or // Circuit using Fleury’s Algorithm using System; using System.Collections.Generic;

class GfG {

// Function to remove edge u-v from the graph
static void removeEdge(List<int>[] adj, int u, int v) {
    adj[u].Remove(v);
    adj[v].Remove(u);
}

// DFS to count reachable vertices from v
static void dfsCount(int v, List<int>[] adj, 
                     bool[] visited) {
    visited[v] = true;

    foreach (int neighbor in adj[v]) {
        if (!visited[neighbor]) {
            dfsCount(neighbor, adj, visited);
        }
    }
}

// Check if edge u-v is a valid next edge to traverse
static bool isValidNextEdge(int u, int v, 
                            List<int>[] adj, int totalV) {

    if (adj[u].Count == 1) {
        return true;
    }

    bool[] visited = new bool[totalV];
    int count1 = 0;
    dfsCount(u, adj, visited);
    foreach (bool x in visited) {
        if (x) {
            count1++;
        }
    }

    removeEdge(adj, u, v);

    Array.Clear(visited, 0, visited.Length);
    int count2 = 0;
    dfsCount(u, adj, visited);
    foreach (bool x in visited) {
        if (x) {
            count2++;
        }
    }

    adj[u].Add(v);
    adj[v].Add(u);

    return count1 == count2;
}

// Recursively collect the Eulerian 
// path/circuit starting from u
static void getEulerUtil(int u, List<int>[] adj, 
                         List<int[]> edges, int v) {

    for (int i = 0; i < adj[u].Count; ++i) {
        int next = adj[u][i];
        if (isValidNextEdge(u, next, adj, v)) {
            edges.Add(new int[] { u, next });
            removeEdge(adj, u, next);
            getEulerUtil(next, adj, edges, v);
            break;
        }
    }
}

// Function to return Eulerian trail or circuit
static List<int[]> getEulerTour(int v, List<int>[] adj) {
    int start = 0;

    // Find a vertex with odd degree if exists
    for (int i = 0; i < v; i++) {
        if (adj[i].Count % 2 != 0) {
            start = i;
            break;
        }
    }

    List<int[]> edges = new List<int[]>();
    getEulerUtil(start, adj, edges, v);
    return edges;
}

static void Main() {
    int v = 4;
    List<int>[] adj = new List<int>[4];
    for (int i = 0; i < 4; i++) {
        adj[i] = new List<int>();
    }
    adj[0].Add(1); adj[0].Add(2);
    adj[1].Add(0); adj[1].Add(2);
    adj[2].Add(0); adj[2].Add(1); adj[2].Add(3);
    adj[3].Add(2);

    List<int[]> res = getEulerTour(v, adj);

    for (int i = 0; i < res.Count; i++) {
        Console.Write(res[i][0] + "-" + res[i][1]);
        if (i != res.Count - 1) {
            Console.Write(", ");
        }
    }
}

}

JavaScript

// Javascript program to print Eulerian Path or // Circuit using Fleury’s Algorithm

// Function to remove edge u-v from the graph function removeEdge(adj, u, v) { adj[u].splice(adj[u].indexOf(v), 1); adj[v].splice(adj[v].indexOf(u), 1); }

// DFS to count reachable vertices from v function dfsCount(v, adj, visited) { visited[v] = true;

for (let neighbor of adj[v]) {
    if (!visited[neighbor]) {
        dfsCount(neighbor, adj, visited);
    }
}

}

// Check if edge u-v is a valid next edge to traverse function isValidNextEdge(u, v, adj, totalV) { if (adj[u].length === 1) { return true; }

let visited = Array(totalV).fill(false);
dfsCount(u, adj, visited);
let count1 = visited.filter(x => x).length;

removeEdge(adj, u, v);

visited.fill(false);
dfsCount(u, adj, visited);
let count2 = visited.filter(x => x).length;

adj[u].push(v);
adj[v].push(u);

return count1 === count2;

}

// Recursively collect the Eulerian // path/circuit starting from u function getEulerUtil(u, adj, edges, v) { for (let i = 0; i < adj[u].length; ++i) { let next = adj[u][i]; if (isValidNextEdge(u, next, adj, v)) { edges.push([u, next]); removeEdge(adj, u, next); getEulerUtil(next, adj, edges, v); break; } } }

// Function to return Eulerian trail or circuit function getEulerTour(v, adj) { let start = 0;

// Find a vertex with odd degree if exists
for (let i = 0; i < v; i++) {
    if (adj[i].length % 2 !== 0) {
        start = i;
        break;
    }
}

let edges = [];
getEulerUtil(start, adj, edges, v);
return edges;

}

// Driver Code let v = 4; let adj = [[1, 2], [0, 2], [0, 1, 3], [2]];

let res = getEulerTour(v, adj);

for (let i = 0; i < res.length; i++) { process.stdout.write(res[i][0] + "-" + res[i][1]); if (i !== res.length - 1) { process.stdout.write(", "); } }

`

**Time Complexity: O(e²), each edge is checked for bridge status using DFS before traversal.
**Space complexity: O(v + e), adjacency list, visited array, and result storage require linear.