对于bfs来说,他的一个重要的线性结构是队列,所以这一篇前面主要讲的是队列的构建和使用
队列就是像我们日常生活中的队伍一样,先进先出。如何使这个数出去呢?这就需要两个整型变量充当指针,这个指针并不是我们c语言中的指针,他是一个变量 int head;int tail;这两个变量的值就是数组的下标。对head和tail进行加减,就是数组中的数进行加减。若head++则head指向下一位,虽然前面的那一位没有真正意义上的删除,但是从head开始到tail结束的数组长度却已经减少了,所以我们仍把这种操作看成对数组的删除。对于tail也是同理。
接下来我来构建一个队列。
#include
int main()
{
int queue[100];//数组使必然需要的
int head=1;//我习惯于数组从1开始
int tail=1;//待会进行输入的时候,我们用tail++,数组长度就会跟着变大
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&queue[tail]);//这样就把数输入的队列中了
tail++;
}
//head指向头,tail指向尾
return 0;
}
具体例子(该图来自《啊哈!算法》,非常感谢该书作者让我受益匪浅)
我按照这个要求来进行构造和使用
按照先前的步骤进行构造。
关键在于如何使用,这个要求里面有几个字眼值得关注,第一是删除,第二就是将最前面移到最后面。删除就是将head++,使头指针指向后一位。而调到后面去则是tail++;quene[tail]=quene[head];head++;tail++为前面调过来的数留出空间,然后再进行赋值。
#include
int main()
{
int data[100];
int head=1;
int tail=1;
for(int i=1;i<=9;i++)
{
scanf("%d",&data[tail]);
tail++;
}
while(head
仔细模拟一下,是不是就是这么一回事。
但在平常的使用中,我们往往使用结构来表示一个队列,按照这个思路不难把结构体形式的队列写出来
#include
struct queen
{
int data[100];
int head;
int tail;
};
int main()
{
struct queen q;
q.head=1;
q.tail=1;
int i=1;
for(int i=1;i<=9;i++)//这个就是用来进行9次循环的,这个变量i没有啥实际用处
{
scanf("%d",&q.data[q.tail]);//不是将i作为下标进行输入而是将q.tail来进行下标变量
q.tail++;
}
while(q.head
很多题解都是c++的题解,而c++的队列使有自己的库函数的,为了为了方便我复习的时候能够看懂题解我把c++的队列形式写一下
q.push(a)//将a插入队列
q.pop()队首出列
q.empty()判断队首是否为空(相当于while(head
1.怎么样将一个数存入进队列?
2.既然没有用到递归,那么是怎么终止的,终止条件又是怎样的?
3.广度优先搜素的模板又是怎样的?
4.常见的题型
我用一个我自己总结的模板就可以回答上面前三个问题
1.构造队列结构体
2.队列初始化,将数据插入到队列的结构体中,仅指第一个(第一个问题)
3.while(head 4.在while循环中做越界判断,标记判断 5.像插入第一个数据一样,利用循环将每一个数据都插入到队列中。 6.终止条件if(tx==q&&ty==p)break;跳出循环(这个条件是下面这道题的终止条件)(第二个问题) 代码形式的模板 此图来自(该图来自《啊哈!算法》,非常感谢该书作者让我受益匪浅) 在上一道的基础上,这一题的思路与上一题相似。在我还没开始学bfs的时候,最令我费神的使这个“日”该怎么走。解决方案,只需要设置一个方向数组,之前我们学dfs的时候,写过上,下,左,右四个方向的,也写过上,下,左,右,右上,右下,左上,左下的。按照我们之前写这些方向数组的思路,就可以将“日”的方向数组搞定。 那这里又会有一个问题,这里没有终点,怎么终止。既然没有终点,那我们只需要静等while(head ok!既然这些疑点已经明白,那就套用模板,代码如下 在使q[tail].step增加的时候,我直接写成了q[]tail].step++。在我们处理队列的时候,head和tail的关系有点类似与数组中a[i]和a[i+1]的关系,使一种相邻关系,所以后者的值的变化往往取决于前者的基础之上。 还是关于队列的处理。有模板固然好,但最好还是按照自己的思路推一遍 思路:最开始head和tail使重合的,我们将第一个放在head和tail重合的位置上,所以我们要留出空间给下一个要插进来的数,所以才tail++,要记住,除了赋值的时候,tail始终指向空。当一系列操作进行完后,队列才向前移动。while(!q.empty)
{
a=q.front();
q.pop;
for(枚举所有情况)
{
if(本状态合法)
{
执行标记指令
q.bush
}
}
}
实际问题(上面第四个问题)
小哼小哈走迷宫
#include
马的遍历
#include
出现的错误和些许经验总结