美文网首页
深度优先和广度优先

深度优先和广度优先

作者: Simplelove_f033 | 来源:发表于2019-03-05 11:30 被阅读0次

1、深度优先

深度优先遍历也叫深度优先搜索(Depth First Search)他的遍历规则:不断地沿着顶点的深方向遍历, 顶点的深度方向是指他的零界点方向,
如图


image.png

给定一图G=<V,E>用vsitted表示顶点i的访问情况, 则初始情况下所有的visited[i]都为false , 假设从顶点V0开始遍历, 则下一个遍历点则是顶点V0的第一个邻接点V1,接着遍历V1第一个邻接点V3~~~~~~~~~~一直到所有的顶点都访问过
假如我要以V0作为初始的顶点,
第一步,找最近的一个邻接点,然后一直遍历,
则遍历的顺序为V0-V1-V3,
第二步, 回溯法

当遍历到V3时发觉没有遍历的节点了,因为V3指向的节点只能说V0, V0已经遍历过, 所以没路可走, 这时候回退到V1, 看看V1是否有遍历的节点,V1没有时回退到V0, 看看V0是否有下一个节点遍历,V0还有个V2没有遍历, 则 遍历V2 ,遍历的顺序为V0-V1-V3-V2--V4
代码如下

    public class ExampleUnitTest {
       @Test
        public void test(){
           Graph graph = new Graph(5);
           //添加图的结构数据
            int[] v0 = new int[]{0, 1, 1, MAX_WEIGHT, MAX_WEIGHT};
            int[] v1 = new int[]{MAX_WEIGHT, 0, MAX_WEIGHT, 1, MAX_WEIGHT};
            int[] v2 = new int[]{MAX_WEIGHT, MAX_WEIGHT, 0, MAX_WEIGHT, MAX_WEIGHT};
            int[] v3 = new int[]{1, MAX_WEIGHT, MAX_WEIGHT, 0, MAX_WEIGHT};
            int[] v4 = new int[]{MAX_WEIGHT, MAX_WEIGHT, 1, MAX_WEIGHT, 0};
            graph.matrix[0] = v0;
            graph.matrix[1] = v1;
            graph.matrix[2] = v2;
            graph.matrix[3] = v3;
            graph.matrix[4] = v4;
            //深度优先
            graph.dfs();
            //广度优先
            graph.bfs();
        }
    }

    /**
     * Created by Jett on 2018/12/21.
     */

    public class Graph {
        public int[] vertices;//顶点集
        public int[][] matrix;//图的边的信息
        public int verticesSize;

        public static final int MAX_WEIGHT = Integer.MAX_VALUE;

        public boolean[] isVisited;

        public Graph(int verticesSize) {
            this.verticesSize = verticesSize;
            vertices = new int[verticesSize];
            matrix = new int[verticesSize][verticesSize];
            isVisited = new boolean[verticesSize];
            for (int i = 0; i < verticesSize; i++) {
                vertices[i] = i;
            }
        }

         /**
         * 获取第一个邻接点
         */
        public int getFirstNeightBor(int v) {
            for (int i = 0; i < verticesSize; i++) {
                if (matrix[v][i] > 0 && matrix[v][i] != MAX_WEIGHT) {
                    return i;
                }
            }
            return -1;
        }

        /**
         * 获取到顶点v的邻接点index的下一个邻接点
         */
        public int getNextNeightBor(int v, int index) {
            for (int i = index + 1; i < verticesSize; i++) {
                if (matrix[v][i] > 0 && matrix[v][i] != MAX_WEIGHT) {
                    return i;
                }
            }
            return -1;
        }
        /**
         * 深度优先(很象二叉树的前序)
         */
        public void dfs() {
            for (int i = 0; i < verticesSize; i++) {
                if (!isVisited[i]) {
                    System.out.println("viested vertice " + i);
                    dfs(i);
                }
            }
        }

        public void dfs(int i) {
            isVisited[i] = true;
            int v = getFirstNeightBor(i);
            while (v != -1) {
                if (!isVisited[v]) {
                    System.out.println("visted vertice " + v);
                    dfs(v);
                }
                v = getNextNeightBor(i, v);
            }
        }

2、广度优先

广度优先遍历也交广度优先搜索(Breadth First Search),他的遍历规则为:
1、先访问完当前的顶点的所有邻接点,
2、先访问顶点的邻接点先于后访问顶点的邻接点被访问
具体说, 给的那个上图G=<V,E>,用visited[i]表示顶点i被访问的情况,初始情况下Visited【i]都为false,假如从顶点V0开始遍历, 则是遍历的顺序为V0-V1-V2, 遍历完V0所有的节点之后, 则从邻接点V1开始, 遍历V1下所有的节点,接着就遍历V2所有的节点,如果后面还有很多的话,以此类推。
代码如下

/**
     * 广度优先
     */
    public void bfs(){
        for (int i = 0; i < verticesSize; i++) {
            isVisited[i]=false;
        }
        for (int i = 0; i < verticesSize; i++) {
            if(!isVisited[i]){
                isVisited[i]=true;
                System.out.println("visited vertice:"+ i);
                bfs(i);
            }
        }
    }

    public void bfs(int i) {
        LinkedList<Integer> queue = new LinkedList<>();
        //找第一个邻接点
        int fn = getFirstNeightBor(i);
        if (fn == -1) {
            return;
        }
        if (!isVisited[fn]) {
            isVisited[fn] = true;
            System.out.println("visted vertice:" + fn);
            queue.offer(fn);
        }
        //开始把后面的邻接点都入队
        int next = getNextNeightBor(i, fn);
        while (next != -1) {
            if (!isVisited[next]) {
                isVisited[next] = true;
                System.out.println("visted vertice:" + next);
                queue.offer(next);
            }
            next = getNextNeightBor(i, next);
        }
        //从队列中取出来一个,重复之前的操作
        while(!queue.isEmpty()){
            int point=queue.poll();//v1  v2
            bfs(point);
        }

    }

相关文章

网友评论

      本文标题:深度优先和广度优先

      本文链接:https://www.haomeiwen.com/subject/tiqnuqtx.html