浅谈数据结构之图的深度优先和广度优先遍历算法(三)

上一篇

图的遍历

深度优先遍历
图的深度优先搜索(Depth First Search),和树的前序遍历比较类似,简称DFS
它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
显然,深度优先搜索是一个递归的过程。

在这里插入图片描述
广度优先遍历
广度优先搜索算法(Breadth First Search),又称为”宽度优先搜索”或”横向优先搜索”,简称BFS。
它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2…的顶点。
在这里插入图片描述

邻接矩阵深度优先遍历算法

public class MatrixNDG {

    /**
     * 图顶点个数
     */
    int size;

    /**
     * 图顶点名称
     */
    char[] vertexs;

    /**
     * 图的关系矩阵
     */
    int[][] matrix;

    /**
     * 构造图
     * @param vertexs 图的所有顶点
     * @param edges 图的关系数组
     */
    public MatrixNDG(char[] vertexs, char[][] edges) {
        size = vertexs.length;
        matrix = new int[size][size];
        this.vertexs = vertexs;
        for (char[] c : edges) {
            // 根据顶点名称确定对应的矩阵下标
            int p1 = getPosition(c[0]);
            int p2 = getPosition(c[1]);
            // 无向图在对称位置存储
            matrix[p1][p2] = 1;
            matrix[p2][p1] = 1;
        }
    }

    private int getPosition(char ch) {
        for (int i = 0; i < vertexs.length; i++) {
            if (vertexs[i] == ch) {
                return i;
            }
        }
        return -1;
    }

    private void print() {
        System.out.print("  ");
        for (char c : vertexs) {
            System.out.print(c + " ");
        }
        System.out.println();
        int k = 0;
        for (int[] i : matrix) {
            System.out.print(vertexs[k++] + " ");
            for (int j : i) {
                System.out.print(j + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
        char[][] edges = new char[][]{{'A', 'C'},
                {'A', 'D'},
                {'A', 'F'},
                {'B', 'C'},
                {'C', 'D'},
                {'E', 'G'},
                {'D', 'G'},
                {'I', 'J'},
                {'J', 'G'},
                {'E', 'H'},
                {'H', 'K'}};
        MatrixNDG pG = new MatrixNDG(vexs, edges);
        pG.print();
        pG.DFS();
    }

    private void DFS() {
        boolean[] beTraversed = new boolean[size];
        System.out.println(vertexs[0] + " ");
        beTraversed[0] = true;
        DFS(0, 0, beTraversed);
    }
    //深度优先递归核心算法
    private void DFS (int x, int y, boolean[] beTraversed) {
        while (y <= size - 1) {
            if (matrix[x][y] != 0 && beTraversed[y] == false) {
                System.out.println(vertexs[y] + " ");
                beTraversed[y] = true;
                DFS(y, 0, beTraversed);
            }
            y++;
        }
    }
}

邻接表深度优先遍历算法

public class ListNDG {

    /**
     * 邻接表节点类, 单链表数据结构
     */
    Vertex[] vertesLists;

    /**
     * 链表大小
     */
    int size;

    class Vertex {
        char ch;
        Vertex next;

        Vertex (char ch) {
            this.ch = ch;
        }
        void add(char ch) {
            Vertex node = this;
            while (node.next != null) {
                node = node.next;
            }
            node.next = new Vertex(ch);
        }
    }

    public ListNDG(char[] vertexs, char[][] edges) {
        size = vertexs.length;
        //确定邻接表大小
        this.vertesLists = new Vertex[size];
        //设置邻接表每一个信息
        for (int i = 0; i < size; i++) {
            this.vertesLists[i] = new Vertex(vertexs[i]);
        }
        //存储信息
        for (char[] c : edges) {
            int p1 = getPosition(c[0]);
            vertesLists[p1].add(c[1]);
            int p2 = getPosition(c[1]);
            vertesLists[p2].add(c[0]);
        }
    }

    private int getPosition(char c) {
        for (int i = 0; i < size; i++) {
            if (vertesLists[i].ch == c) {
                return i;
            }
        }
        return -1;
    }

    public void print() {
        for (int i = 0; i < size; i++) {
            Vertex temp = vertesLists[i];
            while (temp != null) {
                System.out.print(temp.ch + " ");
                temp = temp.next;
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
        char[][] edges = new char[][]{{'A', 'C'},
                {'A', 'D'},
                {'A', 'F'},
                {'B', 'C'},
                {'C', 'D'},
                {'E', 'G'},
                {'D', 'G'},
                {'I', 'J'},
                {'J', 'G'},
                {'E', 'H'},
                {'H', 'K'}};
        ListNDG pG = new ListNDG(vexs, edges);
        pG.print();
        pG.DFS();
    }

    public void DFS() {
        boolean[] beTraversed = new boolean[size];
        for (int i = 0; i < size; i++) {
            if (!beTraversed[i]) {
                DFS(beTraversed, vertesLists[i]);
            }
        }
    }
    //深度优先遍历核心算法
    private void DFS(boolean[] beTraversed, Vertex temp) {
        System.out.println(temp.ch + " ");
        beTraversed[getPosition(temp.ch)] = true;
        while (temp != null) {
            if (!beTraversed[getPosition(temp.ch)]) {
                DFS(beTraversed, vertesLists[getPosition(temp.ch)]);
            }
            temp = temp.next;
        }
    }
}

邻接矩阵广度优先遍历算法

public class MatrixNDG {

    /**
     * 图顶点个数
     */
    int size;

    /**
     * 图顶点名称
     */
    char[] vertexs;

    /**
     * 图的关系矩阵
     */
    int[][] matrix;

    /**
     * 构造图
     * @param vertexs 图的所有顶点
     * @param edges 图的关系数组
     */
    public MatrixNDG(char[] vertexs, char[][] edges) {
        size = vertexs.length;
        matrix = new int[size][size];
        this.vertexs = vertexs;
        for (char[] c : edges) {
            // 根据顶点名称确定对应的矩阵下标
            int p1 = getPosition(c[0]);
            int p2 = getPosition(c[1]);
            // 无向图在对称位置存储
            matrix[p1][p2] = 1;
            matrix[p2][p1] = 1;
        }
    }

    private int getPosition(char ch) {
        for (int i = 0; i < vertexs.length; i++) {
            if (vertexs[i] == ch) {
                return i;
            }
        }
        return -1;
    }

    private void print() {
        System.out.print("  ");
        for (char c : vertexs) {
            System.out.print(c + " ");
        }
        System.out.println();
        int k = 0;
        for (int[] i : matrix) {
            System.out.print(vertexs[k++] + " ");
            for (int j : i) {
                System.out.print(j + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
        char[][] edges = new char[][]{{'A', 'C'},
                {'A', 'D'},
                {'A', 'F'},
                {'B', 'C'},
                {'C', 'D'},
                {'E', 'G'},
                {'D', 'G'},
                {'I', 'J'},
                {'J', 'G'},
                {'E', 'H'},
                {'H', 'K'}};
        MatrixNDG pG = new MatrixNDG(vexs, edges);
        pG.print();
        System.out.println("++++++++++++++++++++++++");
        pG.BFS();
    }
    private void BFS() {
        boolean[] beTraversed = new boolean[size];
        System.out.println(vertexs[0] + " ");
        beTraversed[0] = true;
        BFS(0, beTraversed);
    }
    //广度优先遍历核心算法
    private void BFS (int x, boolean[] beTraversed) {
        LinkedList<Character> list = new LinkedList<>();
        int y = 0;
        while (y <= size - 1) {
            if (matrix[x][y] != 0 && beTraversed[y] == false) {
                System.out.println(vertexs[y] + " ");
                beTraversed[y] = true;
                list.add(vertexs[y]);
            }
            y++;
        }
        while (!list.isEmpty()) {
            char ch = list.pop();
            int index = this.getPosition(ch);
            BFS(index, beTraversed);
        }
    }
}

邻接表广度优先遍历算法

public class ListNDG {

    /**
     * 邻接表节点类, 单链表数据结构
     */
    Vertex[] vertesLists;

    /**
     * 链表大小
     */
    int size;

    class Vertex {
        char ch;
        Vertex next;

        Vertex (char ch) {
            this.ch = ch;
        }
        void add(char ch) {
            Vertex node = this;
            while (node.next != null) {
                node = node.next;
            }
            node.next = new Vertex(ch);
        }
    }

    public ListNDG(char[] vertexs, char[][] edges) {
        size = vertexs.length;
        //确定邻接表大小
        this.vertesLists = new Vertex[size];
        //设置邻接表每一个信息
        for (int i = 0; i < size; i++) {
            this.vertesLists[i] = new Vertex(vertexs[i]);
        }
        //存储信息
        for (char[] c : edges) {
            int p1 = getPosition(c[0]);
            vertesLists[p1].add(c[1]);
            int p2 = getPosition(c[1]);
            vertesLists[p2].add(c[0]);
        }
    }

    private int getPosition(char c) {
        for (int i = 0; i < size; i++) {
            if (vertesLists[i].ch == c) {
                return i;
            }
        }
        return -1;
    }

    public void print() {
        for (int i = 0; i < size; i++) {
            Vertex temp = vertesLists[i];
            while (temp != null) {
                System.out.print(temp.ch + " ");
                temp = temp.next;
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'};
        char[][] edges = new char[][]{{'A', 'C'},
                {'A', 'D'},
                {'A', 'F'},
                {'B', 'C'},
                {'C', 'D'},
                {'E', 'G'},
                {'D', 'G'},
                {'I', 'J'},
                {'J', 'G'},
                {'E', 'H'},
                {'H', 'K'}};
        ListNDG pG = new ListNDG(vexs, edges);
        pG.print();
        System.out.println("++++++++++++++++++++++++++");
        pG.BFS();
    }

    private void BFS() {
        boolean[] beTraversed = new boolean[size];
        System.out.println(vertesLists[0].ch);
        beTraversed[0] = true;
        BFS(0, beTraversed);
    }

    private void BFS(int x, boolean[] beTraversed) {
        Vertex temp = vertesLists[x];
        LinkedList<Vertex> list = new LinkedList<>();
        while (temp != null) {
            if (!beTraversed[getPosition(temp.ch)]) {
                System.out.println(temp.ch);
                beTraversed[getPosition(temp.ch)] = true;
                list.add(temp);
            }
            temp = temp.next;
        }
        while (!list.isEmpty()) {
            Vertex vertex = list.pop();
            int index = getPosition(vertex.ch);
            BFS(index, beTraversed);
        }
    }
}

原创文章 29 获赞 81 访问量 1万+

猜你喜欢

转载自blog.csdn.net/cuixhao110/article/details/103404039