图的连通性 int-dfs(int-graph[MAXNODES][MAXNODES],int-visted[],int-start){ int堆栈[MAXNODES]; int-top=-1,i; 访问[开始]=1; 堆栈[++顶部]=开始; while(顶部!=-1) { 开始=堆栈[顶部]; 对于(i=0;i
您需要存储从一个节点移动到下一个节点所生成的边。然后您可以验证图中的所有节点都是通过边连接的。请参阅我前面关于强连接组件的问题 您的dfs在编写时也非常低效,因为您从i=0开始重复扫描;您的堆栈应该记住停止的位置并从那里继续。递归更自然,但如果您有有限的调用堆栈大小,则显式堆栈最好(仅适用于巨树) 这是一个递归dfs。如果您对存储dfs树不感兴趣,可以将1存储在Preference[]中,而不是从中访问它的节点): 这可以在没有goto的情况下构建(它只是一个命名的continue to the outmost循环),但在我看来没有任何真正的清晰性图的连通性 int-dfs(int-graph[MAXNODES][MAXNODES],int-visted[],int-start){ int堆栈[MAXNODES]; int-top=-1,i; 访问[开始]=1; 堆栈[++顶部]=开始; while(顶部!=-1) { 开始=堆栈[顶部]; 对于(i=0;i,graph,depth-first-search,Graph,Depth First Search,您需要存储从一个节点移动到下一个节点所生成的边。然后您可以验证图中的所有节点都是通过边连接的。请参阅我前面关于强连接组件的问题 您的dfs在编写时也非常低效,因为您从i=0开始重复扫描;您的堆栈应该记住停止的位置并从那里继续。递归更自然,但如果您有有限的调用堆栈大小,则显式堆栈最好(仅适用于巨树) 这是一个递归dfs。如果您对存储dfs树不感兴趣,可以将1存储在Preference[]中,而不是从中访问它的节点): 这可以在没有goto的情况下构建(它只是一个命名的continue to the
无论如何,递归调用要简单得多。有递归伪代码,你可以相当直接地转录。如果你需要帮助,可以使其非递归(显式堆栈),询问。运行Dijkstra算法。如果队列末尾是空的,并且一些顶点没有着色,则图形没有连接。这是保证线性时间的,dfs方法具有二次最坏情况分析。关于非递归的警告:我最初在没有意识到的情况下得到了非常错误的dfs。除非创建一个堆栈数据结构,其中递归中每个局部变量或参数都有一个成员,如果发生变化,则通过机械方式进行转换,很容易搞乱。仅使用一个堆栈(加上输出前置数组)使它变得非常复杂。dfs_iter的i=n+1部分正是比您的版本更高效的部分,您总是在i=0时重新启动。show(n,pred)是做什么的。您是否尝试显示任何值?是的。我实际上运行并调试了它,因为它非常容易出错。请注释掉该节目或放入您自己的printf。
int dfs(int graph[MAXNODES][MAXNODES],int visited[],int start) {
int stack[MAXNODES];
int top=-1,i;
visited[start]=1;
stack[++top]=start;
while(top!=-1)
{
start=stack[top];
for(i=0;i<MAXNODES;i++) {
if(graph[start][i]&&visited[i]==0) {
stack[++top]=i;
printf("%d-",i);
visited[i]=1;
break;
}
}
if(i==MAXNODES)
top--;
}
return 0;
}
const unsigned MAXNODES=100;
/* predecessor must be 0-initialized by the caller; nodes graph[n] that are
reached from start will have predecessor[n]=p+1, where graph[pred] is the
predecessor via which n was reached from graph[start].
predecessor[start]=MAXNODES+1 (this is the root of the tree; there is NO
predecessor, but instead of 0, I put a positive value to show that it's
reached).
graph[a][b] is true iff there is a directed arc from a->b
*/
void dfs(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start,unsigned pred=MAXNODES)
{
if (predecessor[start]) return;
predecessor[start]=pred+1;
for (unsigned i=0;i<MAXNODES;++i)
if (graph[start][i])
dfs(graph,predecessor,i,start);
}
void dfs_iter(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start)
{
unsigned stack[MAXNODES]; // node indices
unsigned n,pred;
int top=0;
stack[top]=start;
for(;;) {
recurse:
// invariant: stack[top] is the next (maybe reached) node
n=stack[top];
if (!predecessor[n]) { // not started yet
pred=top>0?stack[top-1]:MAXNODES;
//show(n,pred);
predecessor[n]=pred+1;
// the first thing we can reach from n
for (unsigned i=0;i<MAXNODES;++i)
if (graph[n][i] && !predecessor[i]) {
stack[++top]=i; goto recurse; // push
}
}
if (top>0) {
pred=stack[top-1];
// the next thing we can reach from pred after n
for (unsigned i=n+1;i<MAXNODES;++i)
if (graph[pred][i]) {
stack[top]=i; goto recurse; // replace top
}
--top;
} else
return;
}
}