直接修改DFS函数参数a为i为何会导致算法运行异常?
直接修改DFS参数a导致遍历失效的原因分析
问题背景
我写了两段C语言实现的DFS(深度优先搜索)代码,第一段直接在循环里修改参数a的值,导致DFS无法正常运行;第二段使用临时变量y存储i的值再调用DFS,就能正常遍历。
第一段代码(存在问题)
void dfs(int a, int virus) { visited[a] =1; for(int i =1; i <= virus; i++) { if(comp[a][i]) { a = i; if(!visited[a]){ dfs(a,virus); } } } }
第二段代码(正常运行)
#include <stdio.h> #define max 101 int com,virus; int comp[max][max]; int visited[max] ={0,}; void dfs(int a, int virus) { visited[a] =1; for(int i =1; i <= virus; i++) { int y; if(comp[a][i]) { y = i; // 如果直接用a = i替代声明y,会出现问题 if(!visited[y]){ dfs(y,virus); } } } } int main() { scanf("%d",&com); scanf("%d",&virus); for(int i =0; i< virus; i++) { int a,b; scanf("%d %d",&a,&b); comp[a][b] = 1; comp[b][a] = 1; } dfs(1,7); }
测试输入示例
7 6 1 2 2 3 1 5 5 2 5 6 4 7
按照预期,DFS应该遍历节点1、2、3、5、6,但使用第一段代码时,遍历到节点3后就停止了。
原因分析
核心问题在于修改了循环依赖的变量a,破坏了当前DFS层的遍历逻辑:
- 初始调用
dfs(1,7)时,a的值是1,循环从i=1到i=7遍历所有节点,检查comp[1][i]是否为1(即节点1和i是否连通)。 - 当
i=2时,comp[1][2]为1,执行a = i将a改成了2,随后递归调用dfs(2,7)。 - 递归返回后,回到当前循环的下一次迭代(
i=3),但此时a的值已经变成了2,后续循环检查的是comp[2][i]而非原本的comp[1][i]。 - 这就导致原本节点1的其他连通节点(比如i=5)再也不会被检查到——因为循环已经跳过了i=5的迭代,且当前
a已经不是1了,后续循环迭代只会基于a=2去判断连通性,自然无法遍历到节点1的其他邻接点。
而第二段代码使用临时变量y存储i,没有修改当前函数的a值,循环始终基于初始传入的a(当前DFS层的起始节点)去遍历所有可能的邻接点,因此能正常完成所有连通节点的遍历。
内容的提问来源于stack exchange,提问作者dongwook hong
相关产品推荐
相关产品推荐

