[英]Checking for a cycle in an undirected graph using DFS?
因此,我为DFS编写了以下代码:
void dfs (graph * mygraph, int foo, bool arr[]) // here, foo is the source vertex
{
if (arr[foo] == true)
return;
else
{
cout<<foo<<"\t";
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
if (arr[k] == false)
{
//cout<<k<<"\n";
dfs(mygraph,k,arr);
//cout<<k<<"\t";
}
it++;
}
}
//cout<<"\n";
}
现在,我阅读了一个无向图,如果在DFS中,它再次返回到同一顶点,则存在一个循环。 因此,我所做的就是
bool checkcycle( graph * mygraph, int foo, bool arr[] )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
result = checkcycle(mygraph,k,arr);
it++;
}
}
return result;
}
但是,我的checkcycle函数即使没有循环也返回true。 这是为什么? 我的功能有问题吗? 没有执行问题,否则我将进行调试,但是在我的逻辑上它们似乎有问题。
请注意,您的函数并没有完全按照您的想象去做。 让我尝试逐步了解这里发生的情况。 假定以下关系:(1,2),(1,3),(2,3)。 我不假设反射性(即(1,2)并不意味着(2,1))。 关系是直接的。
check cycle
。 此时,2也标记为已访问。 false
false
true
。 您需要一堆访问的节点,或者仅搜索原始节点。 堆栈也将检测子周期(不包括原始节点的周期),但它还会占用更多内存。
编辑:节点堆栈不仅是一堆true
/ false
值,而是一堆节点编号。 如果节点在堆栈中,则已在当前堆栈跟踪中访问过该节点。
但是,还有一种更友好的内存方式:set arr[foo] = false;
随着电话的消失。 像这样:
bool checkcycle( graph * mygraph, int foo, bool arr[], int previousFoo=-1 )
{
bool result = false;
if (arr[foo] == true)
{
result = true;
}
else
{
arr[foo] = true;
auto it = mygraph->edges[foo].begin();
while (it != mygraph->edges[foo].end())
{
int k = *it;
// This should prevent going back to the previous node
if (k != previousFoo) {
result = checkcycle(mygraph,k,arr, foo);
}
it++;
}
// Add this
arr[foo] = false;
}
return result;
}
我认为应该足够了。
编辑:现在应该支持无向图。 节点:此代码未经测试
编辑:有关更详尽的解决方案,请参见“ 紧密连接的组件”
编辑:尽管在评论中给出了具体的解决方案,但这个答案是市场接受的。 阅读评论以获取详细信息。
在checkcycle开始之前,arr []中的所有布尔值都设置为false吗?
您确定节点的迭代器不会在遍历的边缘上加倍(因此,无论周期如何,都多次看到起始节点)?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.