11#include " ../Headers/0003_Graph/0006_EulerianPathAndCircuit.h"
2+ #include < stack>
3+ #include < algorithm>
24using namespace std ;
35
46namespace EulerianPathAndCircuit
57{
68 Node::Node (int value)
79 {
810 this ->data = value;
9- this ->visited = false ;
1011 this ->degree = 0 ;
12+ this ->inDegree = 0 ;
13+ this ->outDegree = 0 ;
14+ this ->visited = false ;
1115 }
1216
1317 // Graph Private Member Methods
@@ -26,18 +30,6 @@ namespace EulerianPathAndCircuit
2630 return node;
2731 }
2832
29- // Graph Public Member Methods
30- void Graph::PushUndirectedEdge (int valueU, int valueV)
31- {
32- Node* nodeU = this ->MakeOrFindNode (valueU);
33- Node* nodeV = this ->MakeOrFindNode (valueV);
34-
35- this ->_adjlist [nodeU].insert (nodeV);
36- nodeU->degree ++;
37- this ->_adjlist [nodeV].insert (nodeU);
38- nodeV->degree ++;
39- }
40-
4133 void Graph::DepthFirstSearch (Node* nodeU)
4234 {
4335 nodeU->visited = true ;
@@ -74,7 +66,7 @@ namespace EulerianPathAndCircuit
7466
7567 this ->DepthFirstSearch (node);
7668
77- // Step-4 : Checking if all the non-zero degree vertexes have been visited or not.
69+ // Step-4 : Checking if all the non-zero degree vertices have been visited or not.
7870 for (auto & iterator : this ->_nodeMap )
7971 {
8072 if (iterator.second ->visited == false && iterator.second ->degree != 0 )
@@ -85,6 +77,50 @@ namespace EulerianPathAndCircuit
8577 return true ;
8678 }
8779
80+ void Graph::EulerianPathHierholzerAlgorithm (Node* startingNode)
81+ {
82+ stack<Node*> currentPath;
83+ currentPath.push (startingNode);
84+ while (!currentPath.empty ())
85+ {
86+ Node* currentNode = currentPath.top ();
87+ if (!this ->_adjlist [currentNode].empty ())
88+ {
89+ Node* nextNode = this ->_adjlist [currentNode].front ();
90+ this ->_adjlist [currentNode].pop_front ();
91+ this ->_adjlist [nextNode].remove (currentNode);
92+ currentPath.push (nextNode);
93+ }
94+ else
95+ {
96+ currentPath.pop ();
97+ this ->_eulerianPath .push_back (currentNode->data );
98+ }
99+ }
100+ }
101+
102+ // Graph Public Member Methods
103+ void Graph::PushUndirectedEdge (int valueU, int valueV)
104+ {
105+ Node* nodeU = this ->MakeOrFindNode (valueU);
106+ Node* nodeV = this ->MakeOrFindNode (valueV);
107+
108+ this ->_adjlist [nodeU].push_back (nodeV);
109+ nodeU->degree ++;
110+ this ->_adjlist [nodeV].push_back (nodeU);
111+ nodeV->degree ++;
112+ }
113+
114+ void Graph::PushDirectedEdge (int valueU, int valueV)
115+ {
116+ Node* nodeU = this ->MakeOrFindNode (valueU);
117+ Node* nodeV = this ->MakeOrFindNode (valueV);
118+
119+ this ->_adjlist [nodeU].push_back (nodeV);
120+ nodeU->outDegree ++;
121+ nodeV->inDegree ++;
122+ }
123+
88124 void Graph::PushSingleNode (int valueU)
89125 {
90126 Node* nodeU = this ->MakeOrFindNode (valueU);
@@ -117,15 +153,15 @@ namespace EulerianPathAndCircuit
117153 return ;
118154 }
119155
120- // Check-2 : When 2 vertex have odd degree, then graph G is Semi-Eulerian.
156+ // Check-2 : When 2 vertices have odd degree, then graph G is Semi-Eulerian.
121157 if (oddDegreeVertexCount == 2 )
122158 {
123159 this ->_isEulerianPathPresent = true ;
124160 this ->_isEulerianCircuitPresent = false ;
125161 return ;
126162 }
127163
128- // Check-3 : When more than 2 vertexes have odd degree, then graph G is Not Eulerian.
164+ // Check-3 : When more than 2 vertices have odd degree, then graph G is Not Eulerian.
129165 if (oddDegreeVertexCount > 2 )
130166 {
131167 this ->_isEulerianPathPresent = false ;
@@ -144,9 +180,34 @@ namespace EulerianPathAndCircuit
144180 return this ->_isEulerianCircuitPresent ;
145181 }
146182
147- // Not properly implemented
148- vector<int > Graph::GetEulerianPath ()
183+ vector<int > Graph::UndirectedGraphGetEulerianPath ()
149184 {
185+ // Case-3 : When more than 2 vertices have odd degree, then the graph G is not Eulerian.
186+ // No Eulerian Path is posible.
187+ if (this ->_isEulerianPathPresent == false )
188+ {
189+ return {};
190+ }
191+
192+ // Now 2 cases remains.
193+ // Case-2 : When 2 vertices have odd degree. Choose any one of them.
194+ Node* node = nullptr ;
195+ for (auto & iterator : this ->_nodeMap )
196+ {
197+ if (iterator.second ->degree & 1 )
198+ {
199+ node = iterator.second ;
200+ break ;
201+ }
202+ }
203+
204+ // Case-1 : When no vertex with odd degree is present. Choose any vertex as starting point.
205+ if (node == nullptr )
206+ {
207+ node = this ->_nodeMap [0 ];
208+ }
209+ this ->EulerianPathHierholzerAlgorithm (node);
210+ reverse (this ->_eulerianPath .begin (), this ->_eulerianPath .end ());
150211 return this ->_eulerianPath ;
151212 }
152213}
0 commit comments