DFS(深度优先搜索)

前言

搜索是一种适用性非常广泛的算法。很多我们实际遇到的问题,数据量可能不会太大,都可以暴力搜索一把来解决。

其实这个算法网上也很多但是都讲的比较复杂很多人也只能看一个前面的东西后面的其实看不懂。也有很多文章讲的不是太精炼,讲不出个所以然来。所以小编今天就利用这篇文章来带大家先入门搜索算法。最简单的 DFS 相当于一个暴力搜索算法。

基本上遇到的很多题目暴力都能解决,毕竟 CPU 处理的速度这么快。

正文

搜索算法是属于一种比较基础的算法,相当于万丈高楼的第一层,也是后期学习的一些高级算法的基础部分,搜索算法分为深度优先搜索(Depth First Search,DFS)和广度优先搜索(Breadth First Search,BFS)这两种。DFS 相对简单一点那就从 DFS 开始入门吧。
在这里插入图片描述
说到这个搜索算法就要讲到图的问题,有学过离散数学或者数据结构的都知道,图是一个点集合加上一个边的集合一个边对应两个定点,属于一种二元关系。

如果你没学过的话上面那句话省略,直接看这里:举个例子讲,微信朋友圈可以看成一个很大的图,每个人都是一个顶点,彼此是好友彼此的朋友圈就能看到,相当于彼此的可达的。这个问题一抽象化就能算出只要你的朋友圈连接着多少人了。假如你发张你的自拍,你的每个好友都转发,你好友的好友也都转发……然后全世界都知道你长什么样子了。 所以小编的文章能怎么样还是需要你们这些第一批种子用户的。

直接形象化的上图
在这里插入图片描述

了解什么是图了,那么我们从图的遍历开始讲,给定一个包含 N N N个顶点的图,以及图上的 M M M条边。让你遍历图中的每一个顶点恰好一次。图的遍历有很多用途,比如判断一个图是不是连通的。和判断你的微信能不能连接全世界是一样的。

我们说说到一个算法首先考虑的是他的实现,要实现的话就得要存储,看问题我们是有两个集合(点集和边集)集合一般的思想就是通过一个数组集合来存储,通过对点集的标号,找到与数组下标的关系,我们就能实现存储。

其实我们有两种方法来存储边集。一种叫做邻接矩阵表示法,另一种叫邻接表表示法。

邻接矩阵是说我们用一个二维矩阵A来表示边集。 A i , j = 0 A_{i,j}=0 Ai,j=0表示顶点 i i i和顶点 j j j之间不存在边, A i , j = 1 A_{i,j}=1 Ai,j=1表示顶点i和顶点j之间存在边。如果我们用邻接矩阵表示上图,是这个样子:
在这里插入图片描述
在程序中,我们一般用一个二维数组来表示邻接矩阵: i n t int int a [ N + 1 ] [ N + 1 ] a[N+1][N+1] a[N+1][N+1] a i , j = = 1 a_{i,j}==1 ai,j==1表示 i i i j j j之间有边相连, a i , j = = 0 a_{i,j}==0 ai,j==0表示 i i i j j j之间没有边相连。

邻接表是图中的每一个顶点i都有一个线性表,保存与i相连的顶点编号。

如果我们用邻接矩阵表示上图,是这个样子:
在这里插入图片描述
在程序中,我们一般用一个数组嵌套vector的方法来表示邻接表: v e c t o r < i n t > vector<int> vector<int> g [ N + 1 ] g[N+1] g[N+1],里面保存着每一个与i相邻的顶点编号。

上面讲了什么是搜索,如何存储一个图。那么重头戏来了我们不妨设从1号顶点起始。在搜索过程中,我们维护一个布尔数组 b o o l bool bool v i s i t e d [ N + 1 ] visited[N+1] visited[N+1],这个数组用来表示每个顶点是不是已经遍历过了。 v i s i t e d i = = t r u e visited_i==true visitedi==true表示顶点 i i i已经遍历过了, v i s i t e d i = = f a l s e visited_i==false visitedi==false表示i还没有遍历过。DFS一般我们可以用递归实现,如果采用邻接矩阵,伪代码如下:

Visited[] = {FALSE, FALSE, ...FALSE}
DFS(x):
  Visited[x] = TRUE
   For i = 1 .. N:
     If !Visited[i] AND A[x][i]:
       DFS(i)

当我们执行 D F S ( 1 ) DFS(1) DFS(1)的时候,程序就会开始从1号节点开始遍历,每一次都对搜索过的书标记一直到全部被标记完为止。而每一次DFS执行中都要i循环从 1 1 1 N N N遍历一遍。所以整个复杂度是 O ( N 2 ) O(N^2) O(N2)的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
深度优先搜索DFS)是一种图遍历算法,适用于解决图的连通性、遍历和寻找路径等问题。在应用DFS算法时,常常需要将图的结构表示为数组。 建立一个DFS深度优先搜索数组时,可以按照以下步骤进行操作: 1. 首先,创建一个与图中顶点数量相等的数组,用于记录每个顶点的访问状态。初始时,将所有的数组元素初始化为未访问状态。 2. 然后,选择一个起始顶点,将其标记为已访问,并将该顶点入栈。 3. 从起始顶点开始,循环执行以下步骤:弹出栈顶元素(当前顶点),并输出该顶点的值; 4. 遍历该顶点的所有邻接顶点,若某个邻接顶点未被访问,则将其标记为已访问,并将其入栈。 5. 若当前顶点没有未被访问的邻接顶点,则继续弹出栈顶元素,即回溯到上一个顶点,直到栈为空。 6. 当图中所有顶点都被访问过后,DFS深度优先搜索结束。 通过上述步骤,我们可以将图的结构以数组的形式表示,并使用DFS算法进行遍历。在数组中,每个元素代表一个顶点,其对应的值表示该顶点是否已经被访问。通过设置一个栈来保存待访问的顶点,不断地出栈和入栈的操作,实现了DFS算法的深度遍历特性。 需要注意的是,数组的索引可以用来唯一标识顶点,索引值对应的元素则表示该顶点的访问状态。此外,可以根据具体需求,对数组进行扩展,以记录其他需要的信息,比如顶点的父节点、访问时间等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值