数据结构与算法系列 -- 图遍历

1.  广度优先搜索(BFS

广度优先搜索(Breadth-First-Search),简称为 BFS。直观地讲,它其实就 是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后是次近的,依次 往外搜索。
 
过程图如下:
 
 
                                   

BFS代码如下:

 

class Graph {
    public int v; //顶点个数
    public LinkedList<Integer>[] adj;//邻接表

    public LinkedList<Integer>[] getAdj() {
        return adj;
    }

    public int getV() {
        return v;
    }

    public Graph(int v){
        this.v = v;
        adj = new LinkedList[v];
        for(int i=0;i<v;i++){
            adj[i] = new LinkedList<Integer>();
        }

    }

    public void addEdge(int s,int t){
        adj[s].add(t);
        adj[t].add(s);
    }


}

public class GraphTest1 {
    //构造图
    public Graph constructGraph(){
        Graph graph = new Graph(8);
        graph.addEdge(0,1);
        graph.addEdge(0,3);
        graph.addEdge(1,0);
        graph.addEdge(1,2);
        graph.addEdge(1,4);
        graph.addEdge(2,1);
        graph.addEdge(2,5);
        graph.addEdge(3,0);
        graph.addEdge(3,4);
        graph.addEdge(4,1);
        graph.addEdge(4,3);
        graph.addEdge(4,5);
        graph.addEdge(4,6);
        graph.addEdge(5,2);
        graph.addEdge(5,4);
        graph.addEdge(5,7);
        graph.addEdge(6,4);
        graph.addEdge(6,7);
        graph.addEdge(7,5);
        graph.addEdge(7,6);
        return graph;
    }

    @Test
    public void test1(){
        BFS(0,7);
        System.out.println();
        BFS1(0,7);
    }

    //广度优先算法
    public void BFS(int s,int t){
        Graph graph = constructGraph();
        int v = graph.getV();
        boolean[]  visited = new boolean[v];
        int[]      prev    = new int[v];
        Queue<Integer> queue = new LinkedList<>();
        queue.add(s);
        visited[s] = true;

        for(int i=0;i<v;i++){
            prev[i] = -1;
        }

        while (!queue.isEmpty()){

            int q = queue.poll();
            for(int a:graph.adj[q]){
                System.out.println(q+" "+a);

                if(!visited[a]){
                    visited[a] = true;
                    prev[a]    = q;
                    if(a==t){
                        print(prev,s,t);
                        return;
                    }
                    queue.add(a);
                }
            }

        }

    }


    void print(int[] prev, int s, int t) { // 递归打印 s->t 的路径
        if(prev[t] != -1 && t != s){
            print(prev,s,prev[t]);
        }
        System.out.print(t+" ");
    }

}

 

2. 深度优先搜索(DFS

深度优先搜索(Depth-First-Search),简称 DFS。
最直观的例子就是“走迷宫”。 假设你站在迷宫的某个岔路口,然后想找到出口。你随意选择一个岔路口来走,走着走着发
现走不通的时候,你就回退到上一个岔路口,重新选择一条路继续走,直到最终找到出口。 这种走法就是一种深度优先搜索策略。

具体DFS的过程如图:

                                   

DFS代码如下:

   

class Graph {
    public int v; //顶点个数
    public LinkedList<Integer>[] adj;//邻接表

    public LinkedList<Integer>[] getAdj() {
        return adj;
    }

    public int getV() {
        return v;
    }

    public Graph(int v){
        this.v = v;
        adj = new LinkedList[v];
        for(int i=0;i<v;i++){
            adj[i] = new LinkedList<Integer>();
        }

    }

    public void addEdge(int s,int t){
        adj[s].add(t);
        adj[t].add(s);
    }


}


public class GraphTest1 {

    public Graph constructGraph(){
        Graph graph = new Graph(8);
        graph.addEdge(0,1);
        graph.addEdge(0,3);
        graph.addEdge(1,0);
        graph.addEdge(1,2);
        graph.addEdge(1,4);
        graph.addEdge(2,1);
        graph.addEdge(2,5);
        graph.addEdge(3,0);
        graph.addEdge(3,4);
        graph.addEdge(4,1);
        graph.addEdge(4,3);
        graph.addEdge(4,5);
        graph.addEdge(4,6);
        graph.addEdge(5,2);
        graph.addEdge(5,4);
        graph.addEdge(5,7);
        graph.addEdge(6,4);
        graph.addEdge(6,7);
        graph.addEdge(7,5);
        graph.addEdge(7,6);
        return graph;
    }


    @Test
    public void DFSTest(){
        Graph graph = constructGraph();
        int v = graph.getV();
        boolean[]  visited = new boolean[v];
        int[]   prev = new int[v];
        for(int i=0;i<v;i++){
            prev[i] = -1;
        }

        DFS(visited,prev,graph,0,6);
        print(prev,0,6);
    }
 //深度遍历算法
    public void DFS(boolean[] visited,int[]  prev,Graph graph,int s,int t){
        visited[s] = true;
        if(s == t) {
            return;
        }



        for(int dd:graph.getAdj()[s]){
            if(!visited[dd]){
                visited[dd] = true;
                prev[dd] = s;
                DFS(visited,prev,graph,dd,t);
            }
        }


    }

    void print(int[] prev, int s, int t) { // 递归打印 s->t 的路径
        if(prev[t] != -1 && t != s){
            print(prev,s,prev[t]);
        }
        System.out.print(t+" ");
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值