欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

深度优先搜索DFS规则及Java实现

程序员文章站 2022-05-22 21:07:39
...

深度优先搜索规则

  1. 如果可能,访问一个邻接的未访问过的定点,标记它,并把它放入栈中
  2. 当不能执行规则1时,如果栈不能为空,就从栈中弹出一个顶点。
  3. 当不能执行规则1和规则2时,就完成了整个的搜索过程。

代码实现:
顶点类

/**
 * 顶点类
 */
public class Vertex {
    public char label;
    public boolean wasVisited;

    public Vertex(char label){
        this.label = label;
    }
}

栈的实现

public class MyStack {
    // 底层是一个数组
    private long[] arr;
    private int top;

    /**
     * 默认构造方法
     */
    public MyStack(){
        arr = new long[10];
        top = -1;
    }

    /**
     * 带参数的构造方法
     */
    public MyStack(int maxSize){
        arr = new long[maxSize];
        top = -1;
    }

    /**
     * 添加数据
     */
    public void push(int value){
        arr[++top] = value;
    }

    /**
     * 移除数据
     */
    public long pop(){
        return arr[top--];
    }

    /**
     * 查看数据
     */
    public long peek(){
        return arr[top];
    }

    /**
     * 判断是否为空
     */
    public boolean isEmpty(){
        return top == -1;
    }

    /**
     * 判断是否满栈
     * @return
     */
    public boolean isFull(){
        return top == arr.length - 1;
    }
}

dfs实现

/**
 * 图的dfs实现
 */

public class Graph {
    // 顶点数组
    private Vertex[] vertexList;
    // 邻接矩阵
    private int[][] adjMat;
    // 顶点的最大数目
    private int maxSize = 20;
    // 当前顶点
    private int nVertex;
    // 栈
    private MyStack stack;

    public Graph(){
        // 顶点数组的初始化
        vertexList = new Vertex[maxSize];
        // 邻接矩阵的初始化
        adjMat = new int[maxSize][maxSize];
        // 赋初始值,
        for (int i = 0; i < maxSize; i++) {
            for(int j = 0; j<maxSize;j++){
                adjMat[i][j] = 0;
            }
        }
        nVertex = 0;
        stack = new MyStack();

    }


    /**
     * 添加顶点
     */
    public void addVertex(char label){
        vertexList[nVertex++] = new Vertex(label);
    }

    /**
     * 添加边
     */
    public void addEdge(int start, int end){
        adjMat[start][end] = 1;
        adjMat[end][start] = 1;
    }

    public int getadjUnvisitedVertex(int v){
        for (int i = 0; i < nVertex; i++) {
            //寻找v节点的邻接点,且没有被访问过
            if(adjMat[v][i] == 1 && vertexList[i].wasVisited == false){
                return i;
            }
        }
        return -1;  // 表示找不到未访问的邻接点
    }


    public void dfs(){
        // 首先访问0号顶点
        vertexList[0].wasVisited = true;
        // 显示该顶点
        displayVertex(0);
        // 压入栈中
        stack.push(0);
        while(!stack.isEmpty()){
            // 获得一个未访问过的邻接点
            int v = getadjUnvisitedVertex((int)stack.peek());
            if(v == -1){
                // 弹出一个顶点
                stack.pop();
            }else{
                vertexList[v].wasVisited = true;
                displayVertex(v);
                stack.push(v);
            }
        }
        // 在搜索完成后,要将访问信息还原
        for(int i = 0; i<nVertex;i++){
            vertexList[i].wasVisited = false;
        }
    }

    public void displayVertex(int v){
        System.out.print(vertexList[v].label);
    }
}