Why I have StackOverflow in DFS?

1

I'm trying to implement a DFS algorithm in c++. I use it to answer the question: "are two vertexes connected or not?", but something went wrong.

Sometimes the program gives correct answer, sometimes crashes with 0xC00000FD code. I've google it and know now, that is a StackOverflow error.

Here's the code:

const int N = 4;                     // The minimal example I've know is a graph with 4 vertexes.
std::vector<int> graph[N];           // Our graph
int start = 0;                       // The start vertex
int finish = N - 1;                  // The finish vertex

bool dfs(int old, int v) {           // The DFS function
    if (v == finish)
        return true;
    bool ans = false;
    for (int u : graph[v]) {
        if (u != old)
            ans |= dfs(v, u);
    }
    return ans;
}

void init_graph_ok() {               // With this graph all works fine
    graph[0] = { 1 };               
    graph[1] = { 2 };                // 0 (st) -- 1 -- 2 -- 3 (fin)
    graph[2] = { 3 };
    graph[3] = {};
}
void init_graph_bad() {              // With this graph I have StackOverflow
    graph[0] = { 1, 2 };
    graph[1] = { 2, 0 };             // 0 (st) -- 1 -- 2 -- 3 (fin)
    graph[2] = { 0, 3 };             // ^--------------^
    graph[3] = {};
}

int main() {
    init_graph_bad();
//  init_graph_ok();
    std::cout << dfs(-1, 0);
}
c++
algorithm
stack-overflow
depth-first-search
asked on Stack Overflow Dec 17, 2020 by Дмитрий Клёпов • edited Dec 17, 2020 by Deepak Tatyaji Ahire

1 Answer

2

This is because your code is visiting a particular node more than once, because of which your code runs into an infinite recursion.

Because of the infinite recursive calls, the stack memory gets filled up completely and finally results into a stack overflow error.

Solution: Allow every node to be visited almost once by using a visited array as follows:

const int N = 4;                     // The minimal example I've know is a graph with 4 vertexes.
std::vector<int> graph[N];           // Our graph
int start = 0;                       // The start vertex
int finish = N - 1;                  // The finish vertex

bool visited[N+1];

bool dfs(int old, int v) {           // The DFS function

    if(visited[v]){
        return true;
    }
    visited[v] = true;
    
    if (v == finish)
        return true;
        
    bool ans = false;
    
    for (int u : graph[v]) {
        if (u != old)
            ans |= dfs(v, u);
    }
    
    return ans;
}

void init_graph_ok() {               // With this graph all works fine
    graph[0] = { 1 };               
    graph[1] = { 2 };                // 0 (st) -- 1 -- 2 -- 3 (fin)
    graph[2] = { 3 };
    graph[3] = {};
}
void init_graph_bad() {              // With this graph I have StackOverflow
    graph[0] = { 1, 2 };
    graph[1] = { 2, 0 };             // 0 (st) -- 1 -- 2 -- 3 (fin)
    graph[2] = { 0, 3 };             // ^--------------^
    graph[3] = {};
    memset(visited, false, N+1);
}

int main() {
    init_graph_bad();
//  init_graph_ok();
    std::cout << dfs(-1, 0);
} 

PS: Do not worry about cycles, as this logic will take care of cycles as well.


User contributions licensed under CC BY-SA 3.0