DFS(深搜)算法

 
深度优先搜索(DFS) 深度优先搜索在搜索过程中访问某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点。 初始条件下所有节点为白色,选择一个作为起始顶点,按照如下步骤遍历: a. 选择起始顶点涂成灰色,表示还未访问 b. 从该顶点的邻接顶点中选择一个,继续这个过程(即再寻找邻接结点的邻接结点),一直深入下去,直到一个顶点没有邻接结点了,涂黑它,表示访问过了 c. 回溯到这个涂黑顶点的上一层顶点,再找这个上一层顶点的其余邻接结点,继续如上操作,如果所有邻接结点往下都访问过了,就把自己涂黑,再回溯到更上一层。 d. 上一层继续做如上操作,知道所有顶点都访问过。 用图可以更清楚的表达这个过程:
1.初始状态,从顶点1开始
2.依次访问过顶点1,2,3后,终止于顶点3
3.从顶点3回溯到顶点2,继续访问顶点5,并且终止于顶点5
4.从顶点5回溯到顶点2,并且终止于顶点2
5.从顶点2回溯到顶点1,并终止于顶点1
6.从顶点4开始访问,并终止于顶点4
从顶点1开始做深度搜索:
  1. 初始状态,从顶点1开始
  2. 依次访问过顶点1,2,3后,终止于顶点3
  3. 从顶点3回溯到顶点2,继续访问顶点5,并且终止于顶点5
  4. 从顶点5回溯到顶点2,并且终止于顶点2
  5. 从顶点2回溯到顶点1,并终止于顶点1
  6. 从顶点4开始访问,并终止于顶点4
演示深度优先搜索的过程
还是引用上篇文章的样例图,起点仍然是V0,我们修改一下题目意思,只需要让你找出一条V0到V6的道路,而无需最短路。
 
假设按照以下的顺序来搜索:
1.V0->V1->V4,此时到底尽头,仍然到不了V6,于是原路返回到V1去搜索其他路径;
2.返回到V1后既搜索V2,于是搜索路径是V0->V1->V2->V6,,找到目标节点,返回有解。
3.1.举例
给出如图3-1所示的图,求图中的V0出发,是否存在一条路径长度为4的搜索路径。
 
 
图3-1
 
显然,我们知道是有这样一个解的:V0->V3->V5->V6。
3.2.处理过程
 
3.3.对应例子的伪代码
这里先给出上边处理过程的对应伪代码。
 
Cpp代码  
  1. /** 
  2.  * DFS核心伪代码 
  3.  * 前置条件是visit数组全部设置成false 
  4.  * @param n 当前开始搜索的节点 
  5.  * @param d 当前到达的深度,也即是路径长度 
  6.  * @return 是否有解 
  7.  */  
  8. bool DFS(Node n, int d){  
  9.     if (d == 4){//路径长度为返回true,表示此次搜索有解  
  10.         return true;  
  11.     }  
  12.   
  13.     for (Node nextNode in n){//遍历跟节点n相邻的节点nextNode,  
  14.         if (!visit[nextNode]){//未访问过的节点才能继续搜索  
  15.   
  16.             //例如搜索到V1了,那么V1要设置成已访问  
  17.             visit[nextNode] = true;  
  18.   
  19.             //接下来要从V1开始继续访问了,路径长度当然要加  
  20.   
  21.             if (DFS(nextNode, d+1)){//如果搜索出有解  
  22.                 //例如到了V6,找到解了,你必须一层一层递归的告诉上层已经找到解  
  23.                 return true;  
  24.             }  
  25.   
  26.             //重新设置成未访问,因为它有可能出现在下一次搜索的别的路径中  
  27.             visit[nextNode] = false;  
  28.   
  29.         }  
  30.         //到这里,发现本次搜索还没找到解,那就要从当前节点的下一个节点开始搜索。  
  31.     }  
  32.     return false;//本次搜索无解  
  33. }  
3.4.DFS函数的调用堆栈
 
此后堆栈调用返回到V0那一层,因为V1那一层也找不到跟V1的相邻未访问节点
 
此后堆栈调用返回到V3那一层
 
此后堆栈调用返回到主函数调用DFS(V0,0)的地方,因为已经找到解,无需再从别的节点去搜别的路径了。
DFS 算法
思想:一直往深处走,直到找到解或者走不下去为止
BFS算法
DFS:使用栈保存未被检测的结点,结点按照深度优先的次序被访问并依次被压入栈中,并以相反的次序出栈进行新的检测。
BFS:使用队列保存未被检测的结点。结点按照宽度优先的次序被访问和进出队列。
 

猜你喜欢

转载自www.cnblogs.com/zhoumin6012/p/9790541.html