图深度优先搜索有时可行,有时则不然

时间:2012-08-22 00:27:55

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

所以我写了一个Graph类,根据节点的顺序,我似乎无法正确地对它进行深度搜索。这就是我的意思:

如果我的图表如下:

A-B-D
|/
C

DFS返回:" ABC"

但看起来像这样:

A-B
| |
D C
|
E

它会正确打印ABCDE。

我发现的问题在于我的getUnvisitedAdjacentNode()函数。这是功能:

    public int getUnvisitedAdjacentNode(int n) {
    for (int i = 0; i < this.nodeList.size(); i++) {
        if (this.edges[n][i] == 1 && this.nodeList.get(i).wasVisited == false) {
            return i;
        }
    }
    return -1;
}

问题,我发现是因为它进入&#34;顺序&#34; (只是for循环),它在第一种情况下永远不会得到遍历D,因为B被访问过,而在C被访问后,B只是从堆栈中弹出。也许这不是问题所在。

这是我实际DFS遍历的代码。

   public void depthFirstTraverse() {
    Stack<Node> stack = new Stack<Node>();

    nodeList.get(0).wasVisited = true;
    System.out.println(nodeList.get(0).item);
    stack.push(nodeList.get(0));

    while (!stack.isEmpty()) {
        int nextNode = this.getUnvisitedAdjacentNode(stack.peek().index);

        if (nextNode == -1) {
            stack.pop();
        } else {
            nodeList.get(nextNode).wasVisited = true;
            System.out.println(nodeList.get(nextNode).item);
            stack.push(nodeList.get(nextNode));
        }
    }
    for (int i = 0; i < nodeList.size(); i++) {
        nodeList.get(i).wasVisited = false;
    }
}

2 个答案:

答案 0 :(得分:2)

幸运的是我发现了自己的错误,上面的代码都是正确的,除了它在我没有粘贴的代码中。

如果有人关心,问题在于我完全忽略了ArrayLists有一个“IndexOf()”方法(愚蠢,我知道)这一事实,并决定将我自己的“索引”字段破解到我的Node类中。在处理我自己的索引时,我有一个小错误,搞砸了遍历。

所以我的DFS算法中的旧行看起来像这样:

int nextNode = this.getUnvisitedAdjacentNode(stack.peek().index);

但它应该是:

int nextNode = this.getUnvisitedAdjacentNode(this.nodeList.indexOf(stack.peek()));

答案 1 :(得分:1)

你说的。如果从堆栈中弹出一个节点,则需要确保其未访问的邻居的所有首先在堆栈中。否则,无法保证每个人都会被访问。

例如,在您给出的第一个图中,如果先访问节点A,然后是节点B,则接下来将访问节点C或D.但是,如果你只将其中一个推入堆栈,然后删除B,则无法到达最后一个。

所以你可能想要做的就是在弹出之前写一个函数getAllUnvisitedAdjacentNodes并将它们的全部推入堆栈。