广度优先搜索

基本步骤:

1.从图中某个顶点v0出发,首先访问v0;

2.依次访问v0的各个未被访问的邻接点;

3.依次从上述邻接点出发,访问它们的各个未被访问的邻接点。

4.若此时图中仍有未被访问的结点,则另选图中的一个未被访问的顶点作为起始点。重复广度优先搜索过程,直到图中的所有节点均被访问过。

基本代码结构

通常用队列(先进先出,FIFO)实现
 
	初始化队列Q.
	Q={起点s}; 
       标记s为己访问;
	while (Q非空) {
		取Q队首元素u; u出队;
		if (u == 目标状态) {}
		所有与u相邻且未被访问的点进入队列;
		标记与u相邻的点为已访问;
	}

在这里插入图片描述

图解
在这里插入图片描述

效率分析

在这里插入图片描述

例题:使用广度优先搜索解决矩阵迷宫问题

步骤

  1. 初始化队列,根据题目的要求使用相关的要求
    1.1 初始化一个队列进行出队和入队邻节点
    1.2 使用节点类进行存储一个节点的前后节点,节点我设置双向,可以左右遍历(可以使用数组)
    1.3 使用List存储相关的节点(可以使用其他的)
    1.4 使用数组存储走过的路径(也可以使用自身的位置改变)
  2. 入队第一个节点,在while循环内遍历所有节点
    2.1 先出队节点,将节点存储到List中
    2.2 判断当前节点是否到了目标点
    2.3 开始循环下上下左右节点,根据条件存入队列中,节点自身标记上一个节点是谁
  3. 取出List列表的末尾节点,根据节点,编序前序节点即可
  public   void breadthFirstSearch(int[][] maze){
        //没有参数的情况
       int[][] map ={/*y*/
          /* x*/{0, 1, 0, 0, 0, 0} ,
                {0, 1, 0, 1, 1, 0},
                {0, 0, 0, 0, 1, 0},
                {0 ,1, 1, 0, 1, 0},
                {1 ,0, 1, 0, 1, 0},
                {1 ,0, 0, 0, 1, 0}
        };
       int m=map.length;
        int n= map[0].length;
        //---------------------------------
        int[] dirx = {0,0,-1,1};
        int[] diry = {-1,1,0,0};// 上下左右
        int[][] visited=new int[m][n]; //用来记录是否访问过
        Node start=new Node(0,0);
        Queue<Node> queue=new LinkedList<Node>();
        ArrayList<Node> arrayList=new ArrayList<Node>();// 用来保存每一个出队列的节点
        queue.offer(start);
        //第二步
        while (!queue.isEmpty()){
            Node local=queue.remove();//取出当前的节点
            arrayList.add(local);//先加入节点
            //如果上次也入队列的节点已经是最后的,则退出
            if (local.x==m-1&&local.y==n-1){
                break;
            }

            for (int i=0;i<4;i++){
                //循环4次,上下左右
                Node nbr=new Node(local.x+dirx[i],local.y+diry[i]);
                if(nbr.x>=0&&nbr.x<m&&nbr.y>=0&&nbr.y<n //边界条件
                           &&map[nbr.x][nbr.y]==0 //下一节点等于0
                        &&visited[nbr.x][nbr.y]==0
                 ){
                    visited[nbr.x][nbr.y]=1;//记录当前的节点
                    queue.offer(nbr);//入栈
                    nbr.prex=local.x;// 保存前驱节点
                    nbr.prey=local.y;// 保存前驱节点

                }//if
            } //for
        }
        //下面使为了方便输出,去除不能联连通的节点 下面的m-1和n-1是寻找的点
         if(arrayList.get(arrayList.size()-1).x!=m-1||arrayList.get(arrayList.size()-1).y!=n-1){// 找到起始节点就停止
            System.out.println("没有找找路径");
            return;
        }
        //第三步,为了输出而已
        Stack<Integer> stack=new Stack<Integer>();
        int  px=arrayList.get(arrayList.size()-1).prex;// 获得目的节点的前驱节点
        int  py=arrayList.get(arrayList.size()-1).prey;

        stack.push(arrayList.size()-1);// 将目的节点在arrayList中的位置记录下来,便于输出
        while (true){
            if(px==0&&py==0){// 找到起始节点就停止
                break;
            }
            for(int i=0;i<arrayList.size();i++){// 循环找出每一个节点的前驱,找到就跳出当前循环
                if(arrayList.get(i).x==px&&arrayList.get(i).y==py){
                    px=arrayList.get(i).prex;
                    py=arrayList.get(i).prey;
                    stack.push(i);// 保存节点在arrayList中的位置
                    break;
                }
            }
        }
        System.out.println("(0,0)");
        while (!stack.isEmpty()){
            System.out.println("("+arrayList.get(stack.peek()).x+","+arrayList.get(stack.peek()).y+")");
            stack.pop();
        }


    }
    class Node{
        int x;
        int y;
        int prex;// 保存前驱节点位置
        int prey;
        Node(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值