1+ #include " ../Headers/0003_Graph/0006_EulerianPathAndCircuit.h"
2+ using namespace std ;
3+
4+ namespace EulerianPathAndCircuit
5+ {
6+ Node::Node (int value)
7+ {
8+ this ->data = value;
9+ this ->visited = false ;
10+ this ->degree = 0 ;
11+ }
12+
13+ // Graph Private Member Methods
14+ Node* Graph::MakeOrFindNode (int value)
15+ {
16+ Node* node = nullptr ;
17+ if (this ->_nodeMap .find (value) == this ->_nodeMap .end ())
18+ {
19+ node = new Node (value);
20+ this ->_nodeMap [value] = node;
21+ }
22+ else
23+ {
24+ node = this ->_nodeMap [value];
25+ }
26+ return node;
27+ }
28+
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+
41+ void Graph::DepthFirstSearch (Node* nodeU)
42+ {
43+ nodeU->visited = true ;
44+ this ->_eulerianPath .push_back (nodeU->data );
45+ for (auto & nodeV : this ->_adjlist [nodeU])
46+ {
47+ if (nodeV->visited == false )
48+ {
49+ this ->DepthFirstSearch (nodeV);
50+ }
51+ }
52+ }
53+
54+ bool Graph::IsConnected ()
55+ {
56+ // Step-1 : Make the visited property of all nodes as false. It is already done in constructor.
57+
58+ // Step-2 : Find a node which do not have 0 degree.
59+ Node* node = nullptr ;
60+ for (auto & iterator : this ->_nodeMap )
61+ {
62+ if (iterator.second ->degree != 0 )
63+ {
64+ node = iterator.second ;
65+ break ;
66+ }
67+ }
68+
69+ // Step-3 : If node is null, it means G.E is null, so G is connected, else call DFS to traverse the graph G.
70+ if (node == nullptr )
71+ {
72+ return true ;
73+ }
74+
75+ this ->DepthFirstSearch (node);
76+
77+ // Step-4 : Checking if all the non-zero degree vertexes have been visited or not.
78+ for (auto & iterator : this ->_nodeMap )
79+ {
80+ if (iterator.second ->visited == false && iterator.second ->degree != 0 )
81+ {
82+ return false ;
83+ }
84+ }
85+ return true ;
86+ }
87+
88+ void Graph::PushSingleNode (int valueU)
89+ {
90+ Node* nodeU = this ->MakeOrFindNode (valueU);
91+ }
92+
93+ void Graph::FindEulerianPathAndCircuit ()
94+ {
95+ // If the graph is not connected then graph G is Not-Eulerian.
96+ if (this ->IsConnected () == false )
97+ {
98+ this ->_isEulerianPathPresent = false ;
99+ this ->_isEulerianCircuitPresent = false ;
100+ return ;
101+ }
102+
103+ int oddDegreeVertexCount = 0 ;
104+ for (auto & iterator : this ->_nodeMap )
105+ {
106+ if (iterator.second ->degree & 1 )
107+ {
108+ oddDegreeVertexCount++;
109+ }
110+ }
111+
112+ // Check-1 : When no vertex with odd degree is present, then graph G is Eulerian.
113+ if (oddDegreeVertexCount == 0 )
114+ {
115+ this ->_isEulerianPathPresent = true ;
116+ this ->_isEulerianCircuitPresent = true ;
117+ return ;
118+ }
119+
120+ // Check-2 : When 2 vertex have odd degree, then graph G is Semi-Eulerian.
121+ if (oddDegreeVertexCount == 2 )
122+ {
123+ this ->_isEulerianPathPresent = true ;
124+ this ->_isEulerianCircuitPresent = false ;
125+ return ;
126+ }
127+
128+ // Check-3 : When more than 2 vertexes have odd degree, then graph G is Not Eulerian.
129+ if (oddDegreeVertexCount > 2 )
130+ {
131+ this ->_isEulerianPathPresent = false ;
132+ this ->_isEulerianCircuitPresent = false ;
133+ return ;
134+ }
135+ }
136+
137+ bool Graph::IsEulerianPathPresent ()
138+ {
139+ return this ->_isEulerianPathPresent ;
140+ }
141+
142+ bool Graph::IsEulerianCircuitPresent ()
143+ {
144+ return this ->_isEulerianCircuitPresent ;
145+ }
146+
147+ // Not properly implemented
148+ vector<int > Graph::GetEulerianPath ()
149+ {
150+ return this ->_eulerianPath ;
151+ }
152+ }
0 commit comments