在此question中提供了DFS伪代码:
DFS(source):
s <- new stack
visited <- {} // empty set
s.push(source)
while (s is not empty):
current <- s.pop()
if (current is in visited):
continue
visited.add(current)
// do something with current
for each node v such that (current,v) is an edge:
s.push(v)
但是,它有一个非常明显的细节-同一节点可以-而且经常-两次被推入堆栈!
1
| \
| 2
| /
3
推1
弹出1
向访问者添加1
推2、3
Pop 2
将2添加到访问的
再次按1键堆叠
...
...
当然,那是不对的?
答案 0 :(得分:3)
您说对了,节点1
将再次被压入堆栈。但这无关紧要:由于已将其标记为“已访问”,因此在下一遍中将基本上将其忽略:
if (current is in visited):
continue
或者,您只能将节点添加到尚未访问的堆栈中:
for each node v such that (current,v) is an edge:
if (v is NOT in visited) s.push(v)
您不太可能在实际实现中添加此检查。但是代码是伪代码,并且通常以非常通用的形式编写,只要算法正确,出于紧凑性和通用性的考虑,这种“优化”或“改进”就省去了。在这里,差异不会影响正确性:在两种情况下,该部分都表示为
// do something with current
将仅对每个节点执行一次 。