是否有DFS的“官方”或什至任何正确的实施方式?

时间:2018-09-03 14:46:56

标签: data-structures graph depth-first-search

在此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键堆叠

...

...

当然,那是不对的?

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

将仅对每个节点执行一次