C++ 为什么我在DFS中有StackOverflow?

C++ 为什么我在DFS中有StackOverflow?,c++,algorithm,stack-overflow,depth-first-search,C++,Algorithm,Stack Overflow,Depth First Search,我试图在c++中实现DFS算法。我用它来回答这个问题:“两个顶点是否连接?”,但出了点问题 有时程序会给出正确答案,有时会因0xc0000fd代码而崩溃。我用谷歌搜索过,现在知道了,这是一个堆栈溢出错误 代码如下: const int N = 4; // The minimal example I've know is a graph with 4 vertexes. std::vector<int> graph[N]; /

我试图在
c++
中实现DFS算法。我用它来回答这个问题:“两个顶点是否连接?”,但出了点问题

有时程序会给出正确答案,有时会因
0xc0000fd
代码而崩溃。我用谷歌搜索过,现在知道了,这是一个堆栈溢出错误

代码如下:

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);
}
const int N=4;//我知道的最简单的例子是一个有4个顶点的图。
std::向量图[N];//我们的图表
int start=0;//起始顶点
int finish=N-1;//终点顶点
booldfs(intold,intv){//dfs函数
如果(v==完成)
返回true;
布尔ans=假;
对于(int u:graph[v]){
如果(u!=旧)
ans |=dfs(v,u);
}
返回ans;
}
void init_graph_ok(){//使用此图,一切正常
图[0]={1};
图[1]={2};//0(st)--1--2--3(fin)
图[2]={3};
图[3]={};
}
void init_graph_bad(){//使用此图,我有堆栈溢出
图[0]={1,2};
图[1]={2,0};//0(st--1--2--3(fin)
图[2]={0,3};//^--------------^
图[3]={};
}
int main(){
init_graph_bad();
//init_graph_ok();

这是因为您的代码不止一次地访问一个特定节点,因此您的代码运行在一个无限递归中

由于无限递归调用,堆栈内存被完全填满,最终导致堆栈溢出错误

解决方案:使用
已访问的
数组,允许每个节点几乎访问一次,如下所示:

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);
} 
const int N=4;//我知道的最简单的例子是一个有4个顶点的图。
std::向量图[N];//我们的图
int start=0;//开始顶点
int finish=N-1;//完成顶点
布尔访问[N+1];
booldfs(intold,intv){//dfs函数
如果(访问[v]){
返回true;
}
访问[v]=正确;
如果(v==完成)
返回true;
布尔ans=假;
对于(int u:graph[v]){
如果(u!=旧)
ans |=dfs(v,u);
}
返回ans;
}
void init_graph_ok(){//使用此图,一切正常
图[0]={1};
图[1]={2};//0(st)--1--2--3(fin)
图[2]={3};
图[3]={};
}
void init_graph_bad(){//使用此图,我有堆栈溢出
图[0]={1,2};
图[1]={2,0};//0(st--1--2--3(fin)
图[2]={0,3};//^--------------^
图[3]={};
memset(已访问,错误,N+1);
}
int main(){
init_graph_bad();
//init_graph_ok();

std::cout通常这是由无限递归调用引起的…使用调试器逐步检查代码,看看会发生什么。即使您只是让它在调试器中运行,它也可能会在错误发生时停止,以便您可以检查所有内容。您的代码无法处理周期是图形。所有递归算法都有一个缺陷:即使如果数据集足够大,则不会导致无限递归,最终会使堆栈溢出。
ans |=dfs(v,u)
看起来像是布尔上的一个逐位运算符。谢谢!现在我知道你是受欢迎的。ё59419。