广度优先搜索较之深度优先搜索之不同在于,深度优先搜索旨在不管有多少条岔路,先一条路走到底,不成功就返回上一个路口然后就选择下一条岔路,而广度优先搜索旨在面临一个路口时,把所有的岔路口都记下来,然后选择其中一个进入,然后将它的分路情况记录下来,然后再返回来进入另外一个岔路,并重复这样的操作。
DFS中我们说关键点是递归以及回溯,在BFS中,关键点则是状态的选取和标记。
DFS和BFS的区别
bfs 遍历节点是先进先出,dfs遍历节点是先进后出;
bfs是按层次访问的,dfs 是按照一个路径一直访问到底,当前节点没有未访问的邻居节点时,然后回溯到上一个节点,不断的尝试,直到访问到目标节点或所有节点都已访问。
bfs 适用于求源点与目标节点距离最近的情况,例如:求最短路径。dfs 更适合于求解一个任意符合方案中的一个或者遍历所有情况,例如:全排列、拓扑排序、求到达某一点的任意一条路径。
模板:
void bfs()
{
初始化,初始状态存数组;
int head=0,tail=1,que[max_size];//构建队列
标记初始点
while(head<tail)
{
head++;//指向待扩展结点
for(i=1;i<=maxi;++i)
{
if(满足条件||不重复)
{
tail++;
将新节点存入队列
}
}
}
}
迷宫:
这个题目我是用深搜来解的广搜还并未完全理解代码所以就等之后再来重新解一遍。、
先上代码
#include<stdio.h>
int m[4][2]={{0,1},
{1,0},
{0,-1},
{-1,0}};
int book[6][6],a[6][6],ex,ey,N,M,step,ways,startx,starty;
void dfs(int x,int y)
{
int tx,ty,k;
if(x==ex&&y==ey)
{
ways++;
return ;}
for(int k=0;k<=3;k++)
{
tx=x+m[k][0];
ty=y+m[k][1];
if(tx<1||ty<1||tx>N||ty>M)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)
{
book[tx][ty]==1;
dfs(tx,ty);
book[tx][ty]=0;
}
}
return ;
}
int main()
{
int T,zx,zy;
scanf("%d%d%d%d%d%d%d", &N, &M, &T, &startx, &starty, &ex, &ey);
book[startx][starty]=1;
for(int i=0;i<T;i++)
{
scanf("%d %d",&zx,&zy);
a[zx][zy]=1;
}
dfs(startx,starty);
printf("%d",ways);
return 0;
}
主要逻辑一步一步的走(就是用递归来实现)假如当前位置是终点位置则方法加1,这里先是往一个方向往死走之后发现到了终点或者是有障碍物碰壁了就返回上一步选择其他方向。注意要确定下一个方向是否已经走过更要注意当回溯时需要把当前那一步视为还未走过。走的方向以及走的步数可以用一个二维数组来确定。
自然数的分离:
先附上代码
#include<stdio.h>
int a[9],n;
void push(int num)
{
for(int i=0;i<num;i++)
{
if(i==0)
printf("%d",a[i]);
else
printf("+%d",a[i]);
}
printf("\n");
return ;
}
void dfs(int x,int sum,int step)
{
if(x==n)
return ;
if(sum==n)
{
push(step);
return ;
}
for(int i=x;i<=n-sum;i++)
{
a[step]=i;
dfs(i,sum+i,step+1);
}
}
int main()
{
scanf("%d",&n);
dfs(1,0,0);
return 0;
}
浅显易懂也是两个方法都能做我只用了深搜的方法。用一给数组来存放各个需要相加的数当相加为输入n时就循环打印出来。这里没有进行回溯是因为其数组的数能进行覆盖,差不多是回溯的效果。
今天对深搜有了更深的理解并对广搜的概念知道,只是对其代码的实现还需要进行再一度的理解。总的来说今天收获满满。