一、DFS与BFS
数据结构 | 空间 | 大致思路 | |
DFS | stack | O(h) | 一条路走到头 |
BFS | queue | O(2^h) | 一层一层搜 |
二、深度优先搜索(DFS)
深度优先搜索与暴搜类似但是剪枝法可以使它更高效。
1、思路:先找一条路走到头无路可走记录方案并回退一格继续向下搜以此递归。
2、注意:1、为减少算法复杂度需要记录之前遍历的结果,后直接调用即可。
2、递归之后需要恢复现场
3、例题:全排列
int n;int path[N];//存方案的
bool st[N];
void dfs(int u)
{
if(u==n)//判断是否为叶节点
{
for(int i=0;i<n;i++)
{
printf("%d",path[i]);
put(" ");
return;
}
for(int i=0;i<n;i++)
{
if(!st[i])
{
path[u]=i;
st[i]=true;
dfs(u+1);//递归
st[i]=false;//恢复现场
}
}
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
三、广度优先搜索(BFS)
一层一层搜,当每一次搜索的权重相同时可以求”最短路“。
框架搜索图
例题:走迷宫
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
typedef pair<int, int> PII;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int g[N][N], dist[N][N], n, m;
PII q[N * N];
int bfs()
{
memset(dist, -1, sizeof dist);
dist[0][0] = 0;
int hh = 0, tt = 0;
q[0] = {0, 0};
while (hh <= tt)
{
PII t = q[hh ++ ];
for (int i = 0; i < 4; i ++ )
{
int a = t.first + dx[i], b = t.second + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m || ~dist[a][b] || g[a][b])
continue;
dist[a][b] = dist[t.first][t.second] + 1;
q[ ++ tt] = {a, b};
}
}
return dist[n - 1][m - 1];
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
scanf("%d", &g[i][j]);
printf("%d\n", bfs());
return 0;
}