Java - 邻接矩阵和DFS

时间:2018-03-19 18:56:33

标签: java depth-first-search adjacency-matrix

我一直致力于在Java中实现DFS的程序(通过将邻接矩阵作为文件的输入)。基本上,假设顶点以数字顺序行进,我想打印顶点变为死角的顺序,图形中连接组件的数量,树边缘和后边缘。但我还没完全到那里。当我运行我的程序时,我得到数字“1”作为输出,仅此而已。我已经尝试调试DFS类的某些部分,但我仍然无法弄清楚我哪里出错了。这是我的代码:

基本的“驱动程序”类:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Driver {

public static void main(String[] args) throws FileNotFoundException {
    Scanner scanner = new Scanner(new File("sample1.txt"));
    scanner.useDelimiter("[\\s,]+");

    int input = scanner.nextInt();
    int[][] adjMatrix = new int[8][8];

    for(int i=0; i < input; i++) {
        for (int j=0; j < input; j++) {
             adjMatrix[i][j] = scanner.nextInt();
        }
    }
    scanner.close();

    new DFS(adjMatrix);

}

}

DFS课程:

import java.util.Stack;

public class DFS {
Stack<Integer> stack;
int first;
int[][] adjMatrix;
int[] visited = new int[7];

public DFS(int[][] Matrix) {

    this.adjMatrix = Matrix;
    stack = new Stack<Integer>();
    int[] node = {0, 1, 2, 3, 4, 5, 6};
    int firstNode = node[0];
    depthFirstSearch(firstNode, 7);
}

public void depthFirstSearch(int first,int n){
     int v,i;

     stack.push(first);

     while(!stack.isEmpty()){
         v = stack.pop();
         if(visited[v]==0) {
             System.out.print("\n"+(v+1));
             visited[v]=1;
         }
         for (i=0;i<n;i++){
             if((adjMatrix[v][i] == 1) && (visited[i] == 0)){
                 stack.push(v);
                 visited[i]=1;
                 System.out.print(" " + (i+1));
                 v = i;
             }
         }
     }
}
}

输入文件中的矩阵如下所示:

0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0

1 个答案:

答案 0 :(得分:0)

看一下这部分:

int input = scanner.nextInt();
int[][] adjMatrix = new int[8][8];

for(int i=0; i < input; i++) {
    for (int j=0; j < input; j++) {
         adjMatrix[i][j] = scanner.nextInt();
    }
}

首先你读了一个数字,input。 然后,您会在每行input列中阅读input行。

这是您的输入数据:

0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0

第一个号码是什么,将由scanner.nextInt()读取。 它是0.所以循环什么都不做。

将数字8添加到输入中,即:

8
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
顺便说一句,确认你已经正确读取矩阵是个好主意。 这是一个简单的方法:

for (int[] row : adjMatrix) {
    System.out.println(Arrays.toString(row));
}

此实施中还有其他几个问题:

  • 7号出现在几个地方。它实际上是深度优先搜索算法中的一个关键值,它实际上是不正确的。它应该是8.它不应该是硬编码的,它应该从矩阵的大小中得出。
  • 在构造函数中进行计算不是一个好习惯。构造函数的目的是创建一个对象。深度优先逻辑可以移动到静态实用程序方法,当前代码中没有任何内容可以保证专用类。

修复上述问题,以及一些小问题,实现可以写得更简单,更清晰:

public static void dfs(int[][] matrix) {
    boolean[] visited = new boolean[matrix.length];

    Deque<Integer> stack = new ArrayDeque<>();
    stack.push(0);

    while (!stack.isEmpty()) {
        int v = stack.pop();
        if (!visited[v]) {
            System.out.print("\n" + (v + 1));
            visited[v] = true;
        }
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[v][i] == 1 && !visited[i]) {
                visited[i] = true;
                stack.push(v);
                v = i;
                System.out.print(" " + (i + 1));
            }
        }
    }
}