广搜优先搜索之迷宫问题

广度优先搜索(Breadth First Serch)


又称宽度优先搜索,其方法是系统的展开并搜索图中的所有节点,以寻找位置,它并不考虑所寻目的地的位置,而是彻底的搜索整张图,直到寻到结果为止。
这里写图片描述
也就是说我们要搜索8这个位置,我们从 9 开始,像网一样铺开,搜索7,在搜索 13,没有找到对应位置,继续搜索6,最后到8这个位置。

以迷宫问题为例:


定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

题目分析:
对于广搜我们要应用模拟队列,和head,tail进行标记路径,并且千万不要忘了标记mark走过的路径。
这里写图片描述
如图所示,对于走过的路径逐一放入队列里,也就是说从(0,0)这个位置只能向左和下移动,那么分别把(0,1),(1,0)分别放入队列当中,他们上一个路径位置是(0,0),之后head++变成1,也就是说再从(0,1)这个位置向外走,分别到达(0,2)和(1,1)那他们head就是1

这里写图片描述

/*广搜就使用了一次的bfs并没有和dfs一样的递归调用*/
#include <iostream>
using namespace std;

int dre[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//分别表示路径下,上,左,右
struct Node{
    int x,y,pre;//当前的x,y的位置和先前路径标记
}que[50];//模拟队列,5*5的迷宫
int mark[5][5];//用来标记走过的位置
/*head就是上一个节点的标记,tail就是紧跟这的那个*/
int head=0;
int tail=0;
int Map[5][5];
void bfs(int startx,int starty,int endx,int endy);
void print(Node path);

int main(){

    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            cin >> Map[i][j];
        }
    }
    bfs(0,0,4,4);//迷宫从(0,0)到(4,4)
    print(que[tail-1]);//因为再bfs当中最后tail多了一个所以要减去

    return 0;
}
void bfs(int startx,int starty,int endx, int endy){

    que[head].x=startx;
    que[head].y=starty;
    que[head].pre=-1;//这里等于-1的原因是第一个head是原点,并没有上一个节点
    mark[startx][starty]=1;//走过所以标记上
    tail++;
    int tx,ty;//移动后的下一个位置
    while(head<tail){
        for(int i=0;i<4;i++){
            tx=que[head].x+dre[i][0];//从当前位置按四个移动方向移动
            ty=que[head].y+dre[i][1];
            if(Map[tx][ty]==1||mark[tx][ty]==1)continue;//说明这个位置已经走过,或者是墙
            if(tx<0||tx>4||ty<0||ty>4)continue;//说明已经走了超过地图边界了
            //队列中存储下这个位置
            que[tail].x=tx;
            que[tail].y=ty;
            que[tail].pre=head;//存储的是上一个位置,也就是从head这个位置沿伸出了四个方向
            tail++;//tail最后一个位置即是(4,4)
            mark[tx][ty]=1;//走过要做标记
            if(tx==endx&&ty==endy)return;//到了地图末端了
        }
        head++;
    }

}
void print(Node path){

    if(path.pre==-1){
        cout <<'('<<path.x <<", "<<path.y<<')'<<endl;
    }
    else{
        print(que[path.pre]);
        cout <<'('<<path.x <<", "<<path.y<<')'<<endl;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值