算法 --- 深度优先遍历、广度优先遍历的Java实现

1.图的构建

以下图为例:

public class Test {

    // 顶点信息
    class Vertex {
        private char label;
        private boolean isUsed;

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

    // 顶点总数
    private final int MAX_VERTS = 20;
    // 存储顶点的数组
    private Vertex vertexList[];
    // 用邻接矩阵来存储各边的关系
    private int adjMat[][];
    // 顶点个数
    private int nVerts;

    public Test() {
        vertexList = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        nVerts = 0;
        for (int i = 0; i < MAX_VERTS; i++) {
            for (int j = 0; j < MAX_VERTS; j++) {
                adjMat[i][j] = 0;
            }
        }
    }

    /** 创建顶点*/
    public void addVertex (char label) {
        vertexList[nVerts++] = new Vertex(label);
    }

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

    /** 打印顶点信息 */
    public void displayVertex (int index) {
        System.out.print(vertexList[index].label);
    }

   
    public static void main(String[] args) {
        Test test = new Test();
        test.addVertex('Q'); // 0
        test.addVertex('M'); // 1
        test.addVertex('N'); // 2
        test.addVertex('P'); // 3
        test.addVertex('R'); // 4
        test.addVertex('O'); // 5
        test.addEdge(0,1); // QM
        test.addEdge(0,2); // QN
        test.addEdge(0,3); // QP
        test.addEdge(1,4); // MR
        test.addEdge(2,5); // NO
        test.addEdge(3,5); // PO
    }

}

2.深度优先搜索(Depth First Search, DFS)--- 栈实现

栈实现:

public class Stack {
    // 栈中的元素总数
    private final int MAX_SIZE = 20;
    // 栈信息
    private int stackList[];
    private int top;

    public Stack() {
        stackList = new int[MAX_SIZE];
        top = -1;
    }

    /** 入栈 */
   public void push(int index) {
     stackList[++top] = index;
   }

   /** 出栈 */
   public int pop(){
       return stackList[top--];
   }

   /** 获取当前栈顶信息 */
   public int peek(){
       return stackList[top];
   }

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

深度优先遍历算法的实现:

public class Test {

    // 顶点信息
    class Vertex {
        private char label;
        private boolean isUsed;

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

    // 顶点总数
    private final int MAX_VERTS = 20;
    // 存储顶点的数组
    private Vertex vertexList[];
    // 用邻接矩阵来存储各边的关系
    private int adjMat[][];
    // 顶点个数
    private int nVerts;
    // 深度遍历算法的实现
    private Stack stack;

    public Test() {
        vertexList = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        nVerts = 0;
        for (int i = 0; i < MAX_VERTS; i++) {
            for (int j = 0; j < MAX_VERTS; j++) {
                adjMat[i][j] = 0;
            }
        }
        stack = new Stack();
    }

    /** 创建顶点*/
    public void addVertex (char label) {
        vertexList[nVerts++] = new Vertex(label);
    }

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

    /** 打印顶点信息 */
    public void displayVertex (int index) {
        System.out.print(vertexList[index].label);
    }

    /** 找到与某一顶点邻接且未被访问的顶点(栈) */
    public int getAdjUnvisitedVertexInStack(int v) {
        for(int i = 0; i < nVerts; i++) {
            //v顶点与i顶点相邻(邻接矩阵值为1)且未被访问 isUsed==false
            if(adjMat[v][i] == 1 && !vertexList[i].isUsed) {
                return i;
            }
        }
        return -1;
    }

    public void depthFirstSearch() {
        //从第一个顶点开始访问
        vertexList[0].isUsed = true;
        displayVertex(0);
        stack.push(0);

        while(!stack.isEmpty()) {
            //找到栈当前顶点邻接且未被访问的顶点
            int v = getAdjUnvisitedVertexInStack(stack.peek());
            if(v == -1) {   //如果当前顶点值为-1,则表示没有邻接且未被访问顶点,那么出栈顶点
                stack.pop();
            }else { //否则访问下一个邻接顶点
                vertexList[v].isUsed = true;
                displayVertex(v);
                stack.push(v);
            }
        }

        //栈访问完毕,重置所有标记位wasVisited=false
        for(int i = 0; i < nVerts; i++) {
            vertexList[i].isUsed = false;
        }
    }


    public static void main(String[] args) {
        Test test = new Test();
        test.addVertex('Q'); // 0
        test.addVertex('M'); // 1
        test.addVertex('N'); // 2
        test.addVertex('P'); // 3
        test.addVertex('R'); // 4
        test.addVertex('O'); // 5
        test.addEdge(0,1); // QM
        test.addEdge(0,2); // QN
        test.addEdge(0,3); // QP
        test.addEdge(1,4); // MR
        test.addEdge(2,5); // NO
        test.addEdge(3,5); // PO
        test.depthFirstSearch(); // 打印结果为:QMRNOP
    }

}

3.广度优先搜索(Breadth First Search, BFS)--- 队列实现

队列实现:

public class Queue {
    // 队列中的元素总数
    private final int MAX_SIZE = 20;
    // 队列信息
    private int queueList[];
    private int front;
    private int rear;

    public Queue() {
        queueList = new int[MAX_SIZE];
        front = 0;
        rear = -1;
    }

    /** 插入 */
   public void insert(int index) {
      if (rear == MAX_SIZE) {
         rear = -1;
      }
      queueList[++rear] = index;
   }

   /** 删除队首元素 */
   public int remove() {
       int temp = queueList[front++];
       if (front == MAX_SIZE) {
         front = 0;
       }
       return temp;
   }

   /** 判断队列是否为空 */
   public boolean isEmpty() {
       return rear + 1 == front || front + MAX_SIZE - 1 == rear;
   }
}

广度优先遍历算法的实现:

public class Test {

    // 顶点信息
    class Vertex {
        private char label;
        private boolean isUsed;

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

    // 顶点总数
    private final int MAX_VERTS = 20;
    // 存储顶点的数组
    private Vertex vertexList[];
    // 用邻接矩阵来存储各边的关系
    private int adjMat[][];
    // 顶点个数
    private int nVerts;
    // 宽度遍历算法的实现
    private Queue queue;

    public Test() {
        vertexList = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        nVerts = 0;
        for (int i = 0; i < MAX_VERTS; i++) {
            for (int j = 0; j < MAX_VERTS; j++) {
                adjMat[i][j] = 0;
            }
        }
        queue = new Queue();
    }

    /** 创建顶点*/
    public void addVertex (char label) {
        vertexList[nVerts++] = new Vertex(label);
    }

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

    /** 打印顶点信息 */
    public void displayVertex (int index) {
        System.out.print(vertexList[index].label);
    }

    /** 找到与某一顶点邻接且未被访问的顶点(队列) */
    public List<Integer> getAdjUnvisitedVertexInQueue(int v) {
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < nVerts; i++) {
            //v顶点与i顶点相邻(邻接矩阵值为1)且未被访问 isUsed==false
            if(adjMat[v][i] == 1 && !vertexList[i].isUsed) {
                list.add(Integer.valueOf(i));
            }
        }
        return list;
    }

    /** 宽度优先遍历 */
    public void breadthFirstSearch() {
        vertexList[0].isUsed = true;
        displayVertex(0);
        queue.insert(0);
        while(!queue.isEmpty()) {
            // 获取队首元素
           int v1 = queue.remove();
           List<Integer> result = getAdjUnvisitedVertexInQueue(v1);
           if (result.size() > 0) {
             result.forEach(item -> {
                 vertexList[item].isUsed = true;
                 displayVertex(item);
                 queue.insert(item);
             });
           }
        }
        //搜索完毕,初始化,以便于下次搜索
        for(int i = 0; i < nVerts; i++) {
            vertexList[i].isUsed = false;
        }

    }

  
    public static void main(String[] args) {
        Test test = new Test();
        test.addVertex('Q'); // 0
        test.addVertex('M'); // 1
        test.addVertex('N'); // 2
        test.addVertex('P'); // 3
        test.addVertex('R'); // 4
        test.addVertex('O'); // 5
        test.addEdge(0,1); // QM
        test.addEdge(0,2); // QN
        test.addEdge(0,3); // QP
        test.addEdge(1,4); // MR
        test.addEdge(2,5); // NO
        test.addEdge(3,5); // PO
        test.breadthFirstSearch(); // 打印结果:QMNPRO
    }

}
发布了42 篇原创文章 · 获赞 3 · 访问量 3928

猜你喜欢

转载自blog.csdn.net/zhangting19921121/article/details/103534076