3、深度优先搜索(DFS)

一、课程目标

  1. 图的遍历
  2. 深度优先搜索(DFS)
  3. 算法实现
  4. 所有路径

二、目标详解

1、图的遍历

图的遍历:从图的某个顶点出发,按照某种搜索方法沿着图的边访问所有顶点,每个顶点仅访问一次。

遍历得到的顶点的序列,称为图遍历序列。显然不同的搜索方法会得到不同的遍历序列。

有两种搜索方法:

  • 深度优先搜索(DFS:Depth First Search)
  • 广度优先搜索(BFS:Breadth First Search)

2、深度优先搜索

从某个顶点v0出发,找到其第一个邻接点v1,从v1开始继续进行深度优先搜索,如果某个顶点没有未访问的邻接点,就沿着原路回溯,一直到所有的顶点都被遍历到(既回溯到开始搜索的地方)。

上图从A点出发做dfs搜索(蓝字表示访问,红字表示回溯):

  1. 访问A点,邻接点有B、F、G,选择B点
  2. 访问B点,邻接点有C、D,选择C点
  3. 访问C点,没有邻接点,返回
  4. 回溯到B点,未访问点有D,选择D点
  5. 访问D点,邻接点有E,选择E点
  6. 访问E点,没有邻接点,返回
  7. 回溯到D点,没有未访问点,返回
  8. 回溯到B点,没有未访问点,返回
  9. 回溯到A点,未访问点有F、G,选择F
  10. 访问F点,没有邻接点,返回
  11. 回溯到A点,未访问点有G,选择G
  12. 访问G点,未访问点有H,选择H
  13. 访问H点,没有邻接点,返回
  14. 回溯到G点,没有未访问点,返回
  15. 回溯到A点,没有未访问点,返回
  16. 回到搜索调用的地方,搜索结束

遍历序列为:ABCDEFGH

理解dfs:尽可能的远离起始点。

3、算法实现

要点描述

  • 根据邻接矩阵(或邻接表)能遍历每个点的邻接点
  • 已经访问的点,用一个桶数组vis[]记录,防止重复经过
  • 一般用递归函数实现递归搜索与无路可走时的回溯
  • 也可以用栈(stack)来实现
dfs(顶点) {
  记录访问;
  for(邻接点)
    if (没有访问过)
      dfs(邻接点);
}

int main(){
  dfs(起始点);
  return 0;
}

注意:dfs遍历时是不需要回溯的,加上回溯就变成了枚举所有的路径

4、所有路径

在dfs里使用vis[N]标记已经访问过的顶点,如果在递归dfs后消除vis[i]的标记,算法就变成了要枚举所有的路径(既回溯算法)。

对于每个路径,需要有获得一个路径状态的明确判断,例如经过的顶点数为n,或者顶点到达某个终点。

然后在这个判断里面,对每个路径状态做判定、求解,例如求最大值之类。

这样子就在dfs的基础上形成了回溯算法:

void dfs(int v) {
  if(v == 终点) { //表示到达终点
    //对路径做判定、求解
    return;
  }

  // 遍历v连接的所有边(有连接且未访问过),标记、递归、回溯
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值