java - 迭代图DFS如何添加后访问?

标签 java graph depth-first-search

所以我尝试实现以下图 DFS 方法:

 /** Performs a depth-first traversal of G over all vertices
 *  reachable from V.  That is, the fringe is a sequence and
 *  vertices are added to it or removed from it at one end in
 *  an undefined order.  After the traversal of all successors of
 *  a node is complete, the node itself is revisited by calling
 *  the postVisit method on it. */
public void depthFirstTraverse(Graph<VLabel, ELabel> G,
                               Graph<VLabel, ELabel>.Vertex v) {
    Stack<Vertex> fringe = new Stack<Vertex>();
    HashSet<Vertex> marked = new HashSet<Vertex>();
    fringe.push(v);
    while (!fringe.isEmpty()) {
        Vertex vert = fringe.pop();
        if (!marked.contains(vert)) {
            marked.add(vert);
            visit(vert);
            for (Edge edge : G.edges(vert)) {
                preVisit(edge, vert);
                fringe.add(edge.getV1());
            }
        }
    }
}

根据我的测试,我的通用算法是正确的,但我仍然缺少最后一句的要求:“在完成节点的所有后继遍历后,通过调用其 postVisit 方法来重新访问节点本身。”

我对如何迭代地添加这个 postVisit 方法感到相当困惑(无法更改函数签名,因此递归是不可能的)。有任何想法吗?

最佳答案

您需要一个堆栈,能够将顶点标记为已访问,并将顶点标记为已处理。只要堆栈不为空,您就可以执行以下操作,其中 v 是堆栈上的顶部顶点。

  • v 既不标记为已访问,也不标记为已处理:将所有未访问的邻居推送到堆栈。重要提示:请勿弹出 v。
  • v 被标记为已访问,但未标记为已处理:这是您在 v 上调用 postVisit 的点。之后,您必须从堆栈中弹出 v 并将其标记为已处理
  • v 被标记为已访问并已处理:只需将 v 从堆栈中弹出,不执行任何操作。

关于java - 迭代图DFS如何添加后访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20309140/

相关文章:

javascript - Sunburst Chart - 添加额外的数据层

ios - 对于 iPhone map 应用程序,如何创建图表?

python - 过滤 NetworkX 图以列出来自具有特定属性的节点的所有边

graph - 为什么 BFS 比 DFS 更适合并行化?

java - 在java中设置png图像的DPI

java - 什么是 Java 中大型列表的最佳列表实现

java - 如何验证 header 中包含 "crit"值的 JWSObject?

java - 线程结束后再次执行

c++ - 森林的 DFS 算法

graph - 使用 DFS 检测图中的循环 : 2 different approaches and what's the difference