zoukankan      html  css  js  c++  java
  • Java数据结构与算法之DFS

    深度优先搜索算法

    1. 深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点,可以这样理解:每次都在访问完当前结点后首先访问当前结点的第一个邻接结点。
    2. 我们可以看到,这样的访问策略是优先往纵向挖掘深入,而不是对一个结点的所有邻接结点进行横向访问。
    3. 显然,深度优先搜索是一个递归的过程。

    算法分析:

    1. 假设起始节点为1;先搜索1节点的右侧邻接节点为2,此时将1节点置为已搜索状态;判断2节点是否为已搜索状态,若未搜索,则将2节点置为已搜索状态;每次都优先搜索判断右侧邻接节点;
    2. 如图所示,若此时已搜索至5节点,发现右侧邻接节点为2且已处于已搜索状态故递归至上一个节点8搜索左侧邻接节点处...层层递归判断至1节点(在图中没有并表明递归路径)
    3. 此时搜索判断1节点的左侧邻接节点3不为已搜索状态,故继续进行先右侧后左侧邻接节点搜索判断操作;
    4. 直至最后一个节点6搜索判断3节点为已搜索状态,故递归至最初的1节点;判断结束,搜索结束

    代码实现:

    // 对dfs进行一个重载,遍历我们所有的结点,并进行dfs
        public List<Integer> DFS() {
            isSreachs = new boolean[vertexList.size()];
            dfsArrays = new ArrayList<>();
            for (int i = 0; i < vertexList.size(); i++) {
                // 遍历所有的结点,进行dfs[回溯]
                if (!isSreachs[i]) {
                    dfsArrays = DFS(isSreachs[i], i);
                }
            }
            return dfsArrays;
        }
    
        public List<Integer> DFS(boolean isSreach, int i) {
        	// 首先我们将该节点添加进数组
            dfsArrays.add(showVertexList(i));
            // 将节点设置为已经访问
            isSreachs[i] = true;
            // 查找节点i的第一个邻接节点w
            int w = getFirstNeighbor(i);
            while (w != -1) { // 说明存在w
                if (!isSreachs[w]) {
                    DFS(isSreachs[w],w);
                }
                // w节点已经被访问过
                w = getNextNeightbor(i,w);
            }
            return dfsArrays;
        }
    
        // 得到第一个邻接结点的下标
        public int getFirstNeighbor(int index) {
            for (int j = 0; j < vertexList.size(); j++) {
                if (edges[index][j] == 1) {
                    return j;
                }
            }
            return -1;
        }
    
        // 根据前一个邻接结点的下标来获取下一个邻接结点
        public int getNextNeightbor(int v1, int v2) {
            for (int i = v2+1; i < vertexList.size(); i++) {
                if (edges[v1][i] == 1) {
                    return i;
                }
            }
            return -1;
        }
    

    实现结果:

    这里的结果与分析的结果有所出入,这是因为分析中借用了树的概念,在实现中需要左右子树递归。而这里则运用了上一节图中邻接矩阵的概念,将边用二维矩阵的形式表示出来,故搜索顺序会有些出入。
    但所用的思想是一致的:一条路走到黑,再回头。

  • 相关阅读:
    如何突破单库性能瓶颈?
    高性能数据库表该如何设计?
    高性能索引该如何设计?(下)
    高性能索引该如何设计?(上)
    MySQL体系结构与存储引擎
    动态ViewPager导航页面
    ViewPager图片轮转带点的
    手动图片横向轮播
    安卓布局中下拉列表框的实现
    安卓中adapter的应用
  • 原文地址:https://www.cnblogs.com/njuptzheng/p/13329974.html
Copyright © 2011-2022 走看看