數據結構與算法之廣度優先

圖的基本知識 圖的表示方法可以參考
圖的表示方法
圖的深度遍歷參考
這裏寫鏈接內容

進入正題
圖的廣度遍歷 顧名思義就是先把該節點的所有相連邊訪問一遍,再將該節點的所有相連節點作爲頂點,將其所有相鄰邊訪問一遍,之後依次類推

依然使用一組圖片來說明

初始

這裏寫圖片描述

第一步
訪問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 

到此廣度優先算法到此差不多結束了

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