从一开始的基础到慢慢进入数论,中间也算是写了一点点代码了。从今天开始就要开始进入图论了,不然一直在基础层面上,数据结果的知识一点都没有去进行涉及。虽然还有很多的内容没有更新完,但是现在还是开始去交叉的进行吧,之前上过数据结构的课,但是coding的能力很弱,现在补一下吧。也算是对这个知识点进行实际的操作吧。
DFS:深度优先搜索,尽量往深处进行,树的前中后遍历从某种意义上来说算是深度优先搜索
BFS:广度优先搜索,从广度上进行出发(类比于水),数的层序遍历其实就是类似于BFS。
这里用树去进行类比
从数据结构上看:DFS使用栈stack,BFS使用的是队列
从空间复杂度上看:DFS的时间复杂度O(n),BFS的时间复杂度为O(
2
n
2^n
2n)
对比:
BFS存在最短路的概念,因为是按层去进行查找。
DFS不具有最短路的性质,因为是从深度从进行出发。
DFS和BFS可能涉及回溯和剪枝
引入例题:
#include <iostream>
#include <vector>
using namespace std;
//DFS俗称暴力搜索,+回溯,回溯之后一定要恢复现场
const int N=10;
//记录方案
int path[N];//记录树的路径
int n;
bool st[N];//表示哪些数被用掉了,用掉了就是true 。
//此时st[N]都是false
void dfs(int u){
if(u==n)//此时表示所有的位置填满了
{
for(int i=0;i<n;i++){
cout<<path[i]<<" ";
}
puts("");//换行
return;
}
//说明没有访问到最底层,数字没有填充完
for(int i=0;i<n;i++){
//!st[i] :表示数没有被用过
if(!st[i]){
path[u]=i;
st[i]=true;//标示的是数字i被用过了
dfs(u+1);//递归到下一层
st[i]=false;//回溯的过程、这个很关键
}
}
}
#include <iostream>
using namespace std;
int main(){
cin>>n;
dfs(0);//从第0开始看,也就是根节点
return 0;
}
DFS的另一个应用:N皇后的问题,顺便复习一下递归。
引入例题:
Acwing-843. n-皇后问题
leetcode-51. N皇后
其实这两个题目一模一样:
这里通过三个方法:
前两个方法采用深度优先搜索:
就是稍微格式上改了一点
#include <iostream>
using namespace std;
const int N=20;
int n;
bool col[N],N_dg[N],P_dg[N];
char oc[N][N];
//深搜的过程
void dfs(int u){
if(u==n){
for(int i=0;i<n;i++){
puts(oc[i]);
}
puts("");
return;
}
for(int i=0;i<n;i++){
//回溯+剪枝
if(!col[i]&&!N_dg[u+i]&&!P_dg[n-u+i]){
oc[u][i]='Q';
col[i]=N_dg[u+i]=P_dg[n-u+i]=true;
dfs(u+1);
col[i]=N_dg[u+i]=P_dg[n-u+i]=false;
oc[u][i]='.';
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
oc[i][j]='.';
}
}
//进行dfs深搜
dfs(0);
return 0;
}
leetcode的题解:
如何从行列去进行深搜呢?常规思路,就像是我们下期一样。
#include <iostream>
using namespace std;
const int N=20;
bool col[N],row[N],N_dg[N],P_dg[N];
char oc[N][N];
int n;//n表示皇后的个数,多少行就存在多少个皇后
//s标示的是皇后的个数
void dfs(int x,int y,int s){
//两种边界条件假设
if(y==n) y=0,x++;
if(x==n){
if(s==n){
for(int i=0;i<n;i++){
puts(oc[i]);
}
puts("");
}
return;
}
//基于两种选择,放皇后和不放皇后
//不放皇后,递归到下一个格子,也就是下一列
dfs(x,y+1,s);
//放皇后 .条件:这一行,这一列,对角线都不允许放皇后
if(!row[x]&&!col[y]&&!N_dg[x+y]&&!P_dg[x-y+n]){
oc[x][y]='Q';
//条件成立,更新条件,放皇后
row[x]=col[y]=N_dg[x+y]=P_dg[x-y+n]=true;
//递归到下一层
dfs(x,y+1,s+1);
row[x]=col[y]=N_dg[x+y]=P_dg[x-y+n]=false;
oc[x][y]='.';
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
oc[i][j]='.';//为了符合格式将每一个二维数组全部填成.
}
}
//从左上角开始去进行搜索,并记录有多少个皇后
//前两个参数为某行某列,第三个参数是皇后个数
dfs(0,0,0);
return 0;
}