什么是真正的迭代深度优先搜索实施建议?

What are some true Iterative Depth First Search implementation suggestions?

所以从我所看到的情况来看,我和大多数人一样认为 DFS 的迭代版本就像迭代 BFS,除了两个区别:用堆栈替换队列并将节点标记为在 POP 之后而不是在 PUSH 之后发现。

最近有两个问题很困扰我:

考虑到所有这些先前的细节,我的问题是要实现真正的迭代 DFS 的方法是什么?

问题1:如果在push前check+mark,使用lessspace但是改变了访问节点的顺序。不过,你会参观一切。

问题 2:您说得对,迭代 DFS 通常会将节点的所有子节点同时放入堆栈。这会增加用于某些图表的 space,但不会改变 最坏情况 space 的用法,而且这是最简单的方法,因此通常没有理由改变那个。

偶尔你知道如果你不这样做会节省很多space,然后你可以编写一个更像递归的迭代DFS。不是将要访问的下一个节点压入堆栈,而是将父节点和其子节点列表中的一个位置或等价物压入栈中,这几乎是递归版本在递归时必须记住的内容。在伪代码中,它看起来像这样:

func DFS(start):
    let visited = EMPTY_SET
    let stack = EMPTY_STACK

    visited.add(start)
    visit(start)
    stack.push( (start,0) )

    while(!stack.isEmpty()):
        let (parent, pos) = stack.pop()
        if (pos < parent.numChildren()):

            let child = parent.child[pos]
            stack.push(parent,pos+1)

            if (!visited.contains(child)):
                visited.add(child)
                visit(child)
                stack.push( (child,0) )

可以看到有点复杂,入栈的记录都是元组,有些情况下很烦人。通常我们会并行使用两个堆栈而不是创建元组来推送,或者我们一次 push/pop 两条记录,具体取决于节点和子列表位置的表示方式。