一、DFS(深度优先搜索)
深度优先搜索(Depth First Search)一种用于遍历或搜索树或图的算法。是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
算法思路:
1.根据题目编写对应的递归函数。
2.不需回溯:统计某点能到达的点的个数
从某点出发进行搜索,对于已经被搜索过的点标记不可访问,对于当前被搜索的点递归搜索周围邻接的点并进行计数,直到无法搜索到合法的点返回。
3.需要回溯:迷宫类问题
由于当前选择的路径未必能够到达目标点,因此需要设置回溯,即:对于该路径下各点的访问状态重置(循环内修改了状态,循环完后将状态恢复(递归函数结束后恢复))。
4.剪枝问题(待续):......
DFS例题
#include<bits/stdc++.h>
using namespace std;
const int N=10;
int n;
int p[N]; //存放排列的数组
bool a[N]; //判断是否有同一个数排列
void dfs (int m)
{
if(m==n) //判断是否所有数字是否排列完
{
for(int i=0;i<n;i++)
{
cout<<" "; //5个常宽
cout<<p[i];
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(!a[i])
{
p[m]=i;
a[i]=true;
dfs(m+1);
a[i]=false;
}
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
二、BFS(广度优先搜索)
广度优先搜索(Breadth-First Search,BFS),目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止,BFS是一层一层的搜索,但能找到两样东西之间的最短距离。
BFS例题:
算法思路:0为可走路,1不可走
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int g[N][N]; //存储地图
int f[N][N]; //存储距离
int n, m;
void bfs(int a, int b)
{
queue<PII> q;
q.push({a, b});
while(!q.empty())
{
PII start = q.front();
q.pop();
g[start.first][start.second] = 1;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
for(int i = 0; i < 4; i++)//往四个方向走
{
int x = start.first + dx[i], y = start.second + dy[i];
if(g[x][y] == 0)//如果还没有走过
{
g[x][y] = 1;
f[x][y] = f[start.first][start.second] + 1;
//从当前点走过去,则距离等于当前点的距离+1.
q.push({x, y});
}
}
}
cout << f[n][m];
}
int main()
{
memset(g, 1, sizeof(g));
cin >> n >>m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
cin >> g[i][j];
}
}
bfs(1,1);
}
两者区别:
区别 | 数据结构 | 空间复杂度 | 最短路性 |
---|---|---|---|
DFS | stack(栈) | O(h)(与其高度成正比) | 不具备 |
BFS | queue(队列) | O(2^h) | 具备 |
深度优先搜索所占空间较少,但搜索后不是其最短路径;广度优先搜索则反之。
空间要求高-深度 算法思路奇怪-深度 求最短-广度