数据结构与算法之广度优先<十三>

图的基本知识 图的表示方法可以参考
图的表示方法
图的深度遍历参考
这里写链接内容

进入正题
图的广度遍历 顾名思义就是先把该节点的所有相连边访问一遍,再将该节点的所有相连节点作为顶点,将其所有相邻边访问一遍,之后依次类推

依然使用一组图片来说明

初始

这里写图片描述

第一步
访问A所有边

这里写图片描述

第二步
访问B所有的边
这里写图片描述

访问C所有的边

这里写图片描述

访问G所有的边 由于G没有未访问的边
所以下一步访问D所有的边 由于 D没有未访问的边
所有下一步访问E所有的边

这里写图片描述

至此所有的节点访问完成
观察规律不难发现 这与树的层次遍历非常像 于是便想到利用队列来实现这一算法
接下来我将使用Java实现这一算法
水平有限 若有错误 欢迎指正

public class BFS {
    private final int MAX = 8;
    GraphByMatrix graphByMatrix = new GraphByMatrix(MAX);
    private Queue<Node> queue;
    private List<Node> nodes;

    class Node {
        String data;
        boolean visited;
        int num;

        public Node(String str, int num) {
            this.data = str;
            this.num = num;
        }
    }

    public BFS() {
        queue = new LinkedList<>();
        nodes = new ArrayList<Node>(MAX);
        for (int i = 0; i < MAX; i++) {
            // 节点内容分别为A-H 对应编号0-7
            nodes.add(new Node(new String(Character.toChars('A' + i)), i));
        }
    }

    public int getNextVertex(Node peek) {
        boolean[][] matrix = graphByMatrix.matrix;
        for (int i = 0; i < matrix.length; i++) {
            // 查找顶点没有访问过的节点
            if (matrix[peek.num][i] == true && nodes.get(i).visited == false) {
                return i;
            }
        }
        return -1;
    }

    // 创建图 测试用
    public void bulid() {
        graphByMatrix.addEdge(0, 1);
        graphByMatrix.addEdge(1, 2);
        graphByMatrix.addEdge(1, 6);
        graphByMatrix.addEdge(2, 3);
        graphByMatrix.addEdge(2, 4);
        graphByMatrix.addEdge(4, 6);
        graphByMatrix.addEdge(4, 7);
        graphByMatrix.addEdge(4, 5);
    }

    // 非递归
    public void BFs() {
        // 起点
        Node node = nodes.get(0);
        System.out.print(node.data + " ");
        node.visited = true;
        // 将起始点加入队列
        queue.add(node);
        while (!queue.isEmpty()) {
            Node peek = queue.peek();
            // 寻找下一个未访问的边
            int nextVertex = getNextVertex(peek);
            // 该节点所有边均访问了
            if (nextVertex == -1) {
                // 将该节点弹出
                queue.poll();
            } else {
                // 有没有访问的节点 将其设为访问过 然后加入队列
                Node nextNode = nodes.get(nextVertex);
                nextNode.visited = true;
                System.out.print(nextNode.data + " ");
                queue.add(nextNode);
            }
        }
    }

测试代码

    public static void main(String[] args) {
        BFS bfs = new BFS();
        bfs.bulid();
        bfs.BFs();

    }
//结果为
A B C G D E F H 

到此广度优先算法到此差不多结束了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章