⭐️前言
是否还在为一个人学习算法没有动力而焦虑?是否还在为找不到学习资料而烦恼?
别犹豫了,赶紧加入万人千题,学习方法,学习资料…你想要的应有尽有!
算法,从来都不是一蹴而就,需要经过一定量的练习与总结才能有所进步。本文是作者的一些解读与感受,难免会有不足之处,欢迎各位批评指正。
一、搜索简述
🔥搜索,可以拆分为“搜”和“索”,先搜查,在索取。
无论是深度还是广度,都是图的一种遍历方式,区别只在于两者的实现方式有所不同。深度优先搜索是先序遍历的推广,而广度优先搜索是中序遍历的推广。
二、深度优先搜索
1.定义
深度优先搜索是以深度为优先,先从V1开始,找到离他最近的节点(V2,V3,V4)(若有多个从最近或最小的先开始),之后把V1”染黑“,从下一个节点(V2,V3,V4)开始重复以上操作,直到到达边界或者找到要的答案。
搜索顺序应为V1->V3->V5->V6->V2->V5->V6->V4->V6
2.代码
下面给出一个深搜框架的一个伪代码
#include<stdio.h>
#define MAXN 1000
int dfs(int v,bool p[]){//存储访问节点的数组可以根据需要改成二维
if(v==n||p[v]) return;//判断是否过界或者是否已经访问过,访问则返回或根据题目意思进行操作
p[v]=1;
for(符合某个搜查法则(图(一般用邻接矩阵),二叉树)){
dfs(v1,p);
}
}
int main(){
bool p[MAXN];
dfs(v1,p);
//根据题意进行操作
return 0;
}
ps:深度优先搜索的框架不唯一,应对不同的题目框架有所不同,但是大体上离不开”搜“和”索“
三、广度优先搜索
1.定义
广度优先搜索是以”广度为优先“,说直白点就是以层为优先,与初始状态越接近的越先考虑。以V1开始,优先搜索V3,V2,V4,之后搜索这三个节点的下面一层节点(即V5,V6),按照之前步骤继续直到到达边界或者找到答案。
搜索顺序为V1->V3->V2->V4->V5->V6
2.代码
下面给出广搜的一个伪代码(此处要用到队列(实际上是先入后出的思想),所以代码应该属于c++的范畴)。
bfs(当前初始状态){
q.push(初始状态);//初始状态入队列
while(!q.empty()){//判断队列是否为空
int(也可以是其他类型) v=q.front();//取出队首来进行判断
q.pop();//把队首出队
for(枚举所有符合题目的状态或要求)
if(符合要求)
q.push(i);//入栈
}
}
ps:上面的伪代码仅仅给了广度搜索实现的一个框架,判断是否结束和路径记录都没有写,需要根据题目要求进行删增。
四、总结
深度优先搜索考虑的是深度,它适合那些只有唯一解(最小解或最大解)的题目,但是可能由于题目时间复杂度的限制,深度可能会搜到一半就超限制了。(但不是说多解不适合深度,要能理解题目的想法,究竟探寻的深度还是广度)。
广度优先搜索考虑的是”广度”,它优先考虑每种状态和初始状态的距离,从广度来理解,每件事情就是从上个时刻(状态)拓展出的新的状态(优先类似于物理上的惠更斯原理)。搜索图的连通性时优先考虑广搜。