BFS速成 优先队列

                                              BFS速成

我是个标题党,哪有什么速成,没有时间的积累是不可能成的。

但是这篇博客可以帮助刚刚入门的朋友们,初步了解BFS。(因为我也是最近才开始去慢慢深入了解BFS的,讲的不会太晦涩)

首先我们了解一下BFS是怎么运作的。

 

本人的疏漏 这里的 3号点应该是 2 

我们开始的起始点是1-1 五角星处,开始搜索。BFS是按层搜索,先把我标记的①处搜索完,顺序无所谓,看你的搜索方向。

我们搜索完

后就要入队。 假设开始队列: queue:(☆,1-1)

搜索第一层后 queue:(①,1-2),(①,2-2),(①,2-1) 我们在搜索之前就要将第0层的出队 也就是五角星。

接下来第二层 queue:(①,2-2),(①,2-1),(②,1-3)

queue:(①,2-1),(②,1-3),(②,2-3),(②,3-2) 这里注意一下,当我们搜索(①,2-2)他的周围有两个②没有被搜索过,所以这里要入队两个。

queue:(②,1-3),(②,2-3),(②,3-2),(②,3-1)现在第二层也搜索完了,接下来都是一样的搜索过程。

下面我们直接看代码吧

 

​typedef struct node
{
    int x,y;
   int time;//权值,看题目而定
} node;//这个是我们队列的结构体
char Map[M][M];//地图建立
int vis[M][M];//检查数组
int n,m;//图的大小,n行,m列
queue<node> q;//建立队列
int dx[8]= {1,0,-1,0,1,-1,-1,1},dy[8]= {0,1,0,-1,1,1,-1,-1};//这个是我们的移动数组,这个数组决定了我们的搜索过程。​

BFS

int bfs(int sx,int sy)
{

    if(!q.empty()) q.pop();//将队列清空
    node t,nt;
    t.x=sx,t.y=sy;
    vis[sx][sy]=1;
    q.push(t);
    while(!q.empty())
    {
        t=q.front();//t为当前的结构体,里面的内容为x,y,cost。横坐标,纵坐标和权值
        q.pop();
        int nx,ny,i,j,k;
        for(k=0; k<8; k++)//这里就是按照走法将当前位置能走到的点全部试一次
        {
            nx=t.x+dx[k];
            ny=t.y+dy[k];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&vis[nx][ny]==0&&Map[nx][ny]=='@')//假设没有越界,且没有被访问
            {
                nt.x=nx;
                nt.y=ny;
                vis[nx][ny]=1;//表示已经访问过
                q.push(nt);//新的结点入队
            }

        }

    }

}

BFS到这里已经讲得差不多了

还有一个地方要讲的就是优先队列。

怎么把优先队列和BFS结合起来。有的题目是要求你求出最小的步数,或者耗时最少,这时候就要用到优先队列了。

优先队列的意思就是 将优先程度大的先出队,也就是允许病人急插队,而不是按照先进先出的原则。

优先队列我这里涉及到了运算符重载

​typedef struct Node
{
    int x,y,time;
    bool operator <(const Node &p) const//这里是重载的小于号
    {
        return time>p.time;//这里的意思就是time大的 优先级小,往后靠,比优先级大的后出队
    }
} Node;
priority_queue<Node> q;//这个队列就是优先队列​

想更深入了解优先队列的朋友https://blog.csdn.net/c20182030/article/details/70757660

最后呢奉上几道BFS入门 ZOJ-1709 POJ-3126 HDU-2717

BFS+优先队列 HDU-1008 (诡异的楼梯)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值