繁体   English   中英

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

[英]Iterative Graph DFS how to add a postvisit?

因此,我尝试实现以下Graph 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而不执行任何操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM