深度优先搜索给出错误的输出

时间:2019-01-07 09:50:53

标签: java graph depth-first-search breadth-first-search

Graph

我编写了以下代码,使用深度优先搜索遍历以上图形,我得到的输出为0 1 3 6 4 5 2。

我想使用DFS检查是否正确的遍历,如果不是,什么是正确的遍历。另外,我需要在代码中进行哪些更改才能带来正确的输出。

byte b = 0b111;

邻接指标

public void DFSTraversal()
{

    int v;
    int vFirst = 0;
    Stack<Integer> st = new Stack<Integer>();
    Boolean[] visited = new Boolean[vert];
    for(int j = 0 ; j < vert ; j++ )
    {
        visited[j] = false;
    }

    // st is a stack
    st.push(vFirst);

    while(!st.isEmpty())
    {
        v = st.peek();
        if(!visited[v])
        {
            System.out.printf("%d " , +v);
            visited[v]=true;
        }

            for (int i = 0; i < vert; i++)
            {
                if ((matrix[v][i] == 1) && (!visited[i]))
                {
                    st.push(i);
                    visited[i] = true;
                    System.out.printf("%d ", +i);
                    v = i;
                }
            }

            st.pop();
    }

2 个答案:

答案 0 :(得分:0)

从图片中,假设顶点的边缘按其指向的节点的顺序递增,则正确的输出为:0 1 3 6 2 4 5。

您遇到的问题是,您已经将动态编程方法与堆栈混合在一起,并将迭代方法与重写for遍历所有顶点进行了混合。如果一个顶点与另一个索引的边比其自身索引的边低,则它不会立即访问该节点,而是求助于堆栈。具有未访问边缘的第一边缘的最后一个顶点。

您可以通过仅使用动态编程方法来解决此问题,然后通过边缘向后循环,如果不使用它们,则将其推入堆栈。这样会将边缘留在堆栈顶部的最低值顶点上,以备下次迭代时使用。

您的深度优先搜索循环将变为:

while (!st.isEmpty()) {
  int vertex = st.pop();
  if (!visited[vertex]) {
    System.out.printf("%d ", vertex);
    visited[vertex] = true;

    for (int i = numVertices - 1; i >= 0; --i) {
      if (edges[vertex][i] == 1 && !visited[i]) {
        st.push(i);
      }
    }
  }
}

这样,您仅使用单个循环(您的while循环),该循环不断从堆栈中弹出。访问顶点时,它将所有未访问的顶点和已连接的顶点以相反的顺序推入堆栈。这意味着顶点的编号最小的子代是下一个要访问的子代(DFS)。如果顶点被访问并且位于堆栈的更深处,则再次访问该顶点时会被忽略,其子顶点也将被忽略(它们也已经被访问过)。

然后可以通过将堆栈放入队列并按递增顺序添加顶点,将其更改为“面包优先搜索”。

答案 1 :(得分:-1)

    public void DFSTraversal() {

        int v;
        int vFirst = 0;
        Stack<Integer> st = new Stack<Integer>();
        Boolean[] visited = new Boolean[vert];
        for (int j = 0; j < vert; j++) {
            visited[j] = false;
        }

        // st is a stack
        st.push(vFirst);

        while (!st.isEmpty()) {
            v = st.pop();
            if (!visited[v]) {
                System.out.printf("%d ", +v);
                visited[v] = true;
            }

            for (int i = 0; i < vert; i++) {
                if ((matrix[v][i] == 1) && (!visited[i])) {
                    st.push(i);
                }
            }

        }
    }

在从堆栈中弹出元素时,应打印输出。如果在要检查当前节点所有相邻节点的for循环中打印它,它将成为广度优先搜索(BFS)而不是DFS。

编辑:

添加了完整代码。