一、搜索
搜索包括:深度优先搜索(DFS)、广度优先搜索(BFS)。
二、深度优先搜索与连通分量
1.深搜主要思想:
深度优先遍历(Depth First Search)的主要思想是首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点。当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直至所有的顶点都被访问过。
我们可以分为三个步骤:
(1)访问指定的起始顶点。
(2)若当前访问的顶点的邻接顶点有未被访问的(通过标记数组实现),则任选一个去访问;反之,退回到最近访问过的顶点;直到与起始点相通的全部顶点访问完毕。
(3)若图中还有顶点未被访问,再选其中一个顶点作为起始顶点进行访问,进行步骤2;反之,遍历结束。
递归实现,一往无前,有路就走,没路返回
f(p)//到了p位置
f(p){
for(每个能走到的位置){
if(位置q没到) {
f(q);
记录q到过了 //作用:防止重复访问vis[]
}
}
返回上一步
}
dfs枚举
常用到i数组做标记,灵活掌握递归函数的传参很重要(一个点 能不能到另一个点)
一般用于迷宫中两个点能否到达
最短路
void dfs(某状态){
if(搜出一种结果) return ;
做出该选择并记录该选择做过;
dfs(选择后的状态)
取消该选择以及对该选择的记录
}
三、广度优先搜索与最短路径
1.广搜主要思想:
广度优先遍历从某个顶点 v 出发,首先访问这个结点,并将其标记为已访问过,然后顺序访问结点v的所有未被访问的邻接点 {vi,..,vj} ,并将其标记为已访问过,然后将 {vi,...,vj} 中的每一个节点重复节点v的访问方法,直到所有结点都被访问完为止。
我们可以分为三个步骤:
(1)使用一个辅助队列 q,首先将顶点 v 入队,将其标记为已访问,然后循环检测队列是否为空。
(2)如果队列不为空,则取出队列第一个元素,并将与该元素相关联的所有未被访问的节点入队,将这些节点标记为已访问。
(3)如果队列为空,则说明已经按照广度优先遍历了所有的节点。
队列实现,稳中求进,由近及远,用队列实现重复
while(队列不为空){
取出队首位置p
for(每个能走到位置q){
q入队
走到q看看
记录q到过了vis[]
返回一步
}
}