Skip to content

Commit 15adfb4

Browse files
Merge pull request #392 from Abdullah-Shah-26/feature/hierholzer_pr
Feature/hierholzer_algorithm pr
2 parents 20d05ae + 6e16681 commit 15adfb4

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Algorithm: Hierholzer’s Algorithm (Eulerian Path / Circuit)
3+
*
4+
* Problem:
5+
* Given a connected graph (directed or undirected), find an Eulerian Path or Circuit.
6+
* - Eulerian Path: visits every edge exactly once.
7+
* - Eulerian Circuit: Eulerian Path that starts and ends on the same vertex.
8+
*
9+
* Eulerian Path Conditions:
10+
* - Undirected: At most 2 vertices have odd degree.
11+
* - Directed: exactly 1 vertex has (out = in + 1), exactly 1 has (in = out + 1),
12+
* all others: indegree == outdegree.
13+
*
14+
* Eulerian Circuit Conditions:
15+
* - Undirected: all vertices have even degree.
16+
* - Directed: indegree == outdegree for every vertex.
17+
*
18+
* Approach (Hierholzer’s Algorithm):
19+
* 1. Pick starting vertex:
20+
* - Circuit → any vertex.
21+
* - Path → vertex with (outdeg > indeg).
22+
* 2. Traverse edges using a stack, removing them as you go.
23+
* 3. If stuck, backtrack → add vertex to final path.
24+
* 4. Reverse final path → Eulerian Path / Circuit.
25+
*
26+
* Complexity:
27+
* - O(E), since each edge is used exactly once.
28+
*/
29+
30+
#include <bits/stdc++.h>
31+
using namespace std;
32+
33+
class Eulerian
34+
{
35+
public:
36+
vector<int> findEulerianPath(int n, vector<vector<int>> &edges)
37+
{
38+
vector<vector<int>> adj(n);
39+
vector<int> indeg(n, 0), outdeg(n, 0);
40+
41+
// Build adjacency list
42+
for (auto &e : edges)
43+
{
44+
int u = e[0], v = e[1];
45+
adj[u].push_back(v);
46+
outdeg[u]++;
47+
indeg[v]++;
48+
}
49+
50+
// Find start node (for path vs circuit)
51+
int start = 0;
52+
for (int i = 0; i < n; i++)
53+
{
54+
if (outdeg[i] - indeg[i] == 1)
55+
start = i; // Eulerian path start
56+
}
57+
58+
vector<int> path, stack = {start};
59+
60+
// Hierholzer’s Algorithm
61+
while (!stack.empty())
62+
{
63+
int u = stack.back();
64+
if (!adj[u].empty())
65+
{
66+
// Go deeper using available edge
67+
int v = adj[u].back();
68+
adj[u].pop_back(); // remove edge u→v
69+
stack.push_back(v);
70+
71+
// 🔎 Visualization step
72+
// cout << "Traverse edge " << u << " -> " << v << endl;
73+
}
74+
else
75+
{
76+
// No more edges → add to path (backtrack)
77+
path.push_back(u);
78+
stack.pop_back();
79+
80+
// 🔎 Visualization step
81+
// cout << "Backtrack: add " << u << " to path" << endl;
82+
}
83+
}
84+
85+
reverse(path.begin(), path.end()); // final path
86+
return path;
87+
}
88+
};
89+
90+
int main()
91+
{
92+
// Example Graph: Eulerian Circuit
93+
int n = 4;
94+
vector<vector<int>> edges = {
95+
{0, 1}, {1, 2}, {2, 0}, {0, 3}, {3, 0}};
96+
97+
Eulerian solver;
98+
vector<int> path = solver.findEulerianPath(n, edges);
99+
100+
cout << "Eulerian Path/Circuit: ";
101+
for (int v : path)
102+
cout << v << " ";
103+
cout << endl;
104+
105+
/*
106+
* Visualization for this graph:
107+
*
108+
* Edges: 0->1, 1->2, 2->0, 0->3, 3->0
109+
*
110+
* Step walk:
111+
* Start at 0
112+
* 0 -> 3
113+
* 3 -> 0
114+
* 0 -> 1
115+
* 1 -> 2
116+
* 2 -> 0
117+
*
118+
* Backtracking order:
119+
* 0 (dead end) → 2 → 1 → 0 → 3 → 0
120+
*
121+
* Final Eulerian Circuit:
122+
* 0 → 3 → 0 → 1 → 2 → 0
123+
*/
124+
}

0 commit comments

Comments
 (0)