图遍历--深度优先和广度优先

图的存储方式有两种:邻接矩阵和邻接表,这两种方式都可以用深度优先和广度优先的方式进行遍历。以下面的图为例说明遍历,其临街矩阵如作图所示。注意后面的代码中,顶点从0开始。
这里写图片描述

1. 深度优先

深度优先基于递归的思想,假设开始从顶点1开始遍历,找到其第一个相邻的顶点2,一直往“深”处遍历,找顶点2的相邻顶点4,再找顶点4的相邻点,直到没有相邻点或者相邻点都被访问过进行回溯,同理对其他顶点进行遍历,直到所有顶点都遍历完成。
关键点:
1. 对已访问过的点标记,使用book[][]数组
2. 结束条件,所有顶点都访问完。
3. 图 矩阵的初始化
java实现如下:

package aha_algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Scanner;

public class Graph {

    static int traversedNum;
    static int totalVertex=5;
    static int[][] graph= new int[5][5];
    static int book[] = new int[5];
    /**
     * @param args
     */
    public static void main(String[] args) {
        initGraph();
        book[0]=1;
        DFS(0);
    }

    public static void DFS(int curVertex){
        System.out.println(curVertex);
        traversedNum++;
        //结束条件
        if(traversedNum==totalVertex)
            return;

        for (int i = 0; i <graph[curVertex].length ; i++) {
            if(graph[curVertex][i]==1 && book[i]!=1){
                book[i]=1;
                DFS(i);
                //不需要清除标记
            }
        }

    }
    //输入图的边,初始化矩阵
    static void initGraph(){
        for (int i = 0; i <5; i++) {
            for (int j = 0; j < 5; j++) {
                graph[i][j]=Integer.MAX_VALUE;
            }
        }
        BufferedReader input =new BufferedReader(new  InputStreamReader(System.in));
        for (int i = 0; i < 5; i++) {
            try {
                String[] inLine=input.readLine().split(" ");

                //双向图
                graph[Integer.valueOf(inLine[0])][Integer.valueOf(inLine[1])]=1;
                graph[Integer.valueOf(inLine[1])][Integer.valueOf(inLine[0])]=1;

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

2. 广度优先

广度优先基于队列实现,遍历顺序是:遍历顶点1,将顶点1的所有邻接点加入对列,直到顶点1的相邻点都在队列了将顶点1出队同时访问顶点1,从顶点1的第一个邻接点2开始,将顶点2的所有相邻顶点放入队列,依次类推。结束条件是队列为空。
关键点:
1. 初始化矩阵
2. 创建队列
3. 遍历顶点的相邻点入队
4. 标记顶点已经被访问
5. 判断是否存在通路

java实现如下:

package aha_algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;

public class Graph {

    static int traversedNum;
    static int totalVertex=5;


    static int[][] graph= new int[5][5];
    static int book[] = new int[5];

    static Queue<Integer> bfsQueue = new ArrayDeque<Integer>();

    /**
     * @param args
     */
    public static void main(String[] args) {
        initGraph();

        bfsQueue.offer(0);
        book[0]=1;//注意标记初始点
        BFS();

    }

    public static void BFS( ){

        while(!bfsQueue.isEmpty()){
            int curVer =bfsQueue.peek();
            for (int i = 0; i < 5; i++) {
                if(graph[curVer][i]==1 && book[i]==0){
                    bfsQueue.offer(i);//将邻接顶点入队
                    book[i]=1;
                }
            }
            System.out.println(curVer);
            bfsQueue.poll();//将已经访问过的顶点出队
        }
    }




    //输入图的边,初始化矩阵
    static void initGraph(){
        for (int i = 0; i <5; i++) {
            for (int j = 0; j < 5; j++) {
                graph[i][j]=Integer.MAX_VALUE;
            }
        }
        BufferedReader input =new BufferedReader(new  InputStreamReader(System.in));
        for (int i = 0; i < 5; i++) {
            try {
                String[] inLine=input.readLine().split(" ");

                //双向图
                graph[Integer.valueOf(inLine[0])][Integer.valueOf(inLine[1])]=1;
                graph[Integer.valueOf(inLine[1])][Integer.valueOf(inLine[0])]=1;

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

深度优先遍历可以查看另一片文章,DFS走迷宫

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
广度优先搜索(BFS)是遍历算法之一,它可以用来寻找一个中的最短路径,或者判断两个节点之间是否连通,或者找到一个节点的所有邻居等。BFS 的思路是从一个起始节点开始,依次遍历它的所有邻居节点,并将这些邻居节点加入队列中,然后继续遍历队列中的节点,直到队列为空为止。 下面是 BFS 的具体解题思路: 1. 初始化: - 将起点放入队列中; - 标记起点为已访问; 2. 开始遍历: - 取出队列中的第一个节点,即当前节点; - 遍历当前节点的所有邻居节点,如果邻居节点没有被访问过,将其加入队列中,并标记为已访问; - 重复步骤 2,直到队列为空为止。 3. 输出结果: - 遍历完所有节点后,可以输出遍历的结果,比如输出每个节点的深度或者距离起点的最短路径等。 下面是一个示例: 假设有如下的: ``` A -- B -- C | | | D -- E -- F ``` 其中,A、B、C、D、E、F 分别代表节点,每条线段代表它们之间的连接关系。 现在要从节点 A 开始进行 BFS 遍历,以下是具体步骤: 1. 初始化: 将节点 A 放入队列中,标记 A 为已访问。 2. 开始遍历: - 取出队列中的第一个节点 A,遍历它的邻居节点 B 和 D,将它们加入队列中并标记为已访问; - 取出队列中的第二个节点 B,遍历它的邻居节点 A、C 和 E,其中 A 已经被访问过了,所以不需要再次访问;将 C 和 E 加入队列中,并标记为已访问; - 取出队列中的第三个节点 D,遍历它的邻居节点 A 和 E,其中 A 已经被访问过了,所以不需要再次访问;E 已经被访问过了,所以也不需要再次访问; - 取出队列中的第四个节点 C,遍历它的邻居节点 B 和 F,其中 B 已经被访问过了,所以不需要再次访问;将 F 加入队列中,并标记为已访问; - 取出队列中的第五个节点 E,遍历它的邻居节点 B、D 和 F,其中 B 和 D 已经被访问过了,所以不需要再次访问;F 已经被访问过了,所以也不需要再次访问; - 取出队列中的第六个节点 F,遍历它的邻居节点 C 和 E,其中 E 已经被访问过了,所以不需要再次访问;C 已经被访问过了,所以也不需要再次访问; - 队列为空,结束遍历。 3. 输出结果: 遍历的结果可以是每个节点的深度或者距离起点的最短路径等,以下是每个节点的深度: ``` A: 0 B: 1 C: 2 D: 1 E: 2 F: 3 ``` 可以看到,节点 A 的深度为 0,它的邻居节点 B 和 D 的深度为 1,它们的邻居节点 C 和 E 的深度为 2,最后节点 F 的深度为 3。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值