一起玩转图论算法(2)图的深度优先遍历

2-1 图的两种形式遍历

所谓图的遍历(_graph traversal_),也称为搜索(_search_),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使

每个顶点仅被访问一次。遍历可以采取两种方法进行:深度优先搜索(DFS,_depth first search_)

和广度优先搜索(BFS,_breadth first search_)。

2-2 图的深度优先遍历伪代码

深度优先搜索是一个递归过程,有回退过程。DFS 算法的思想是:对一个无向连通图,在访问图中某一起始顶点 v 后,由 v 出、

发,访问它的某一邻接顶点 _w_1;再从 _w_1出发,访问与 _w_1邻接但还没有访问过的顶点 _w_2;然后再从 _w_2出发,进行类似的访

问;…;如此进行下去,直至到达所有邻接顶点都被访问过的顶点 u 为止;接着,回退一步,回退到前一次刚访问过的顶点,看

是否还有其它没有被访问过的邻接顶点,如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就

再回退一步进行类似的访问。重复上述过程,直到该连通图中所有顶点都被访问过为止。

一起玩转图论算法(2)图的深度优先遍历_第1张图片

树的前序遍历,与图的深度优先遍历的比较:

一起玩转图论算法(2)图的深度优先遍历_第2张图片

2-3 DFS逻辑的微观解读,深度优先遍历顺序

深度优先遍历的递归的遍历形式:

一起玩转图论算法(2)图的深度优先遍历_第3张图片

一起玩转图论算法(2)图的深度优先遍历_第4张图片

一起玩转图论算法(2)图的深度优先遍历_第5张图片

2-4 实现图的深度优先遍历

连通图的深度优先遍历

-结合上述的伪代码

package graphDFS;

import java.util.ArrayList;


public class GraphDFS {
    
    // 创建一个数组,
    private ArrayList res = new ArrayList<>();  // 输出最后深度优先遍历的结果
    private boolean[] visited;
    
    private Graph graph;
    public GraphDFS(Graph graph) {
        this.graph = graph;  
        visited = new boolean[graph.V()]; // 结点的数量
        dfs(0);
    }
    
    private void dfs(int v) {
        visited[v] = true;
        res.add(v);
        for (int w: graph.adj(v)) {  // 遍历该节点的相邻结点
            if (! visited[w])
                dfs(w);
        }
        
    }
    
    public Iterable res(){
        return res;
    }

    public static void main(String[] args) {
        Graph graph = new Graph("g2.txt");
        GraphDFS graphDFS = new GraphDFS(graph);
        System.out.println(graphDFS.res());
//        [0, 1, 3, 2, 6, 5, 4]
    }

}

2-5 图的深度优先遍历的改进

如果不是联通图的话,孤立的结点将不会遍历。

一起玩转图论算法(2)图的深度优先遍历_第6张图片

package graphDFS;

import java.util.ArrayList;


public class GraphDFS {
    
    // 创建一个数组,
    private ArrayList res = new ArrayList<>();  // 输出最后深度优先遍历的结果
    private boolean[] visited;
    
    private Graph graph;
    public GraphDFS(Graph graph) {
        this.graph = graph;  
        visited = new boolean[graph.V()]; // 结点的数量
        //dfs(0);
        // 改进的地方:对每一个结点进行遍历
        for (int v = 0; v < graph.V(); v++) {
            if (!visited[v]) {
                dfs(v);
            }
        }
    }
    
    private void dfs(int v) {
        visited[v] = true;
        res.add(v);
        for (int w: graph.adj(v)) {  // 遍历该节点的相邻结点
            if (! visited[w])
                dfs(w);
        }
        
    }
    
    public Iterable res(){
        return res;
    }

    public static void main(String[] args) {
        Graph graph = new Graph("g2.txt");
        GraphDFS graphDFS = new GraphDFS(graph);
        System.out.println(graphDFS.res());
//        [0, 1, 3, 2, 6, 5, 4]
    }

}


。。。。。。。。。。。。。end。。。。。。。。。。。。。


你可能感兴趣的:(图论,算法,数据结构)