I need to convert Trajan's recursive algorithm to Trajan's iterative algorithm.I have a class Graph it contains several methods and fields here is the basic structure that will be needed
class Graph {
protected:
vector< vector<int> > adjList;
int n;
This is what the recursive code looks like
void DFSforTarjan(int u, vector<bool>& visited,
set<int>& AP, vector<int>& disc, vector<int>& low, int& time, int parent) {
int children = 0;
visited[u] = true;
disc[u] = low[u] = ++time;
for (int v : this->getNeighborVertex(u)) {
if (!visited[v]) {
children++;
DFSforTarjan(v, visited, AP, disc, low, time, u);
low[u] = min(low[u], low[v]);
if (parent != -1 && low[v] >= disc[u])
AP.insert(u);
}
else if (v != parent)
low[u] = min(low[u], disc[v]);
}
if (parent == -1 && children > 1)
AP.insert(u);
}
And this is the code that I tried to implement iteratively, but it does not work properly, please help
void DFSforTarjan(int u, vector<bool>& visited,
set<int>& AP, vector<int>& disc, vector<int>& low, vector<int>& parent, vector<int>& children, int& time) {
stack<int> st;
st.push(u);
while (!st.empty()) {
u = st.top();
st.pop();
if (parent[u] != -1) {
children[parent[u]]++;
}
visited[u] = true;
disc[u] = low[u] = ++time;
for (int v : this->getNeighborVertex(u)) {
if (!visited[v]) {
st.push(v);
parent[v] = u;
visited[v] = true;
}
else if (v != parent[u]) {
low[u] = min(low[u], disc[v]);
}
}
if (parent[u] == -1 && children[u] > 1)
AP.insert(u);
if (parent[u] != -1 && low[u] >= disc[parent[u]])
AP.insert(parent[u]);
}
for (int v : this->getNeighborVertex(u)) {
if (v != parent[u] && visited[v]) {
low[u] = min(low[u], low[v]);
}
}
}
When designing a recursive function it is important to minimize the use of stack memory. So, reduce the number of parameters used on each call by making the recursive function the method of a class. Then, instead of passing the references to the graph details, visited vertices, etc. you can access them directly as attributes of the class.
( The same effect can also be achieved by making those parameters global, but this is frowned upon because your code becomes vulnerable to global name collisions, which can be tricky to debug hence the expression for this: polluting the global namespace )
Here is the definition of a class which implements Tarjan with just three parameters.
and here is the implementation
Complete code and docs at https://github.com/JamesBremner/PathFinder.
This code can handle, without exhausting the default stack size, a graph with 4,720 vertices 13,722 edges from https://dyngraphlab.github.io/ (
3elt.graph.seq.txt) in 27 seconds.If stack memory is still being exhausted you can increase it's size by using the method described in this answer: https://stackoverflow.com/a/54838059/16582