这篇关于DFS算法的帖子对吗?

时间:2017-10-07 12:58:59

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

Show the problem about DFS algorithm

出了什么问题?我认为必须改变第4号堆[G P E]。

当我访问顶点P时,有没有办法可以跳过顶点G?

我认为没有办法。这是错的吗?

3 个答案:

答案 0 :(得分:0)

  

出了什么问题?

没有

  

我认为必须改变第4号堆[G P E]。

不,它不应该。您希望堆栈顶部的元素有顶部。 ' G'必须出现在深度优先遍历的末尾,因此将它放在堆栈的底部是一个好主意。

最后会弹出位于堆栈底部的元素。 首先会弹出堆栈顶部的元素。

答案 1 :(得分:0)

这是标准DFS算法的变体。在标准算法中,您不会将当前节点的未访问邻居全部放在堆栈上,而只放置节点本身,然后访问一个邻居。在对该邻居执行DFS之后,您将回溯并且查看其他子项。如果其中仍然存在未访问的那个,只有它才被推入堆栈。

但是这个替代方案 - 所有未经访问的邻居在深化之前都被放在堆栈上 - 也会很好。

当您将一个节点放在堆栈上时,您还应将其标记为 stacked ,这是在图遍历期间永远不会再次删除的标记,即使该节点稍后从堆栈中弹出。这样,您可以确保在整个遍历期间永远不会将一个节点放在堆栈上。

当到达节点P时,P的所有邻居(即G和H)之前已经被堆叠(H已从其中拉出,并且G仍然在其上)。由于没有P的其他邻居,这个DFS算法从堆栈中拉出下一个节点(即E)以继续遍历。

这是一个JavaScript实现:

class Node {
    constructor(name) {
        this.name = name;
        this.neighbors = [];
    }
    link(node) { // link nodes in both directions
        this.neighbors.push(node);
        node.neighbors.push(this);
    }
    toString() { // The string representation of the node is its name
        return this.name;
    }
    dfs() { // Main algorithm
        const stack = [this], // Start with this node on the stack
            stacked = new Set(stack); // ...and mark it as stacked

        while (stack.length > 0) { // While the stack is not empty...
            console.log('stack: ' + stack);
            const node = stack.pop(); // Pull next node from the top of the stack
            for (const neighbor of node.neighbors) {
                // Only push neighbors on the stack
                // that were never stacked before:
                if (!stacked.has(neighbor)) {
                    stack.push(neighbor); // Push on the stack,
                    stacked.add(neighbor); // ... and mark as stacked
                }
            }
        }
    }
}

// Define nodes:
const a = new Node('A'),
      e = new Node('E'),
      g = new Node('G'),
      h = new Node('H'),
      j = new Node('J'),
      m = new Node('M'),
      p = new Node('P'),
      x = new Node('X'),
      y = new Node('Y');

// Define the links between the nodes
a.link(x);
x.link(g);
x.link(h);
g.link(h);
g.link(p);
h.link(e);
h.link(p);
e.link(m);
e.link(y);
y.link(m);
m.link(j);

// Visit the nodes of the graph, starting at A
a.dfs();
.as-console-wrapper { max-height: 100% !important; top: 0; }

请注意,如果图形是树,那么遍历树的DFS遍历永远不会遇到之前已访问过的节点,因此在这种情况下不需要这样的标记。但是你的图是一个无向的循环图,所以需要这个额外的标记。

答案 2 :(得分:0)

这是DFS。您可以按任何顺序将它们推入堆栈。现在发行。 DFS有很多深度遍历的方法。