定义:

(维基百科:https://en.wikipedia.org/wiki/Depth-first_search)

深度优先搜索算法(Depth-First-Search),是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止(属于盲目搜索)。

基本思想:

(1)访问顶点v;

(2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

(3)重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

算法复杂度:

若有v个顶点、E条边,则

用邻接表储存图,有O(V+E)

用邻接矩阵储存图,有O(V^2)

伪代码:

递归实现:

(1)访问顶点v;visited[v]=1;//算法执行前visited[n]=0

(2)w=顶点v的第一个邻接点;

(3)while(w存在)

if(w未被访问

从顶点w出发递归执行该算法;

w=顶点v的下一个邻接点;

  1. //布尔型数组Visited[]初始化成false
  2. void DFS(Vetex v)
  3. {
  4. Visited[v] = true;
  5. for each w adjacent to v
  6. if (!Visited[w])
  7. DFS(w);
  8. }

非递归实现:

(1)栈S初始化;visited[n]=0;

(2)访问顶点v;visited[v]=1;顶点v入栈S

(3)while(栈S非空)

x=栈S的顶元素(不出栈);

if(存在并找到未被访问的x的邻接点w)

访问w;visited[w]=1;

w进栈;

else

x出栈;

  1. //布尔型数组Visited[]初始化成false
  2. void DFS(Vertex v)
  3. {
  4. Visited[v] = true;
  5. Stack sta = MakeStack(MAX_SIZE);
  6. Push(sta, v);
  7. while (!Empty(sta))
  8. {
  9. Vertex w = Pop(sta);
  10. for each u adjacent to w
  11. {
  12. if (!Visited[u])
  13. {
  14. Push(sta, u);
  15. Visited[u] = true;
  16. }
  17. }
  18. }
  19. }

附:用C语言写一个走迷宫

具体内容为:
1、输入长宽和迷宫地图(‘#’代表墙,‘.'代表空地)
2、输入起点和终点坐标
3、用深度优先算法查找起点到终点的最短路径并显示出来
  1. #include <stdio.h>
  2.  
  3. char map[][]; //地图上限50*50
  4. int sign[][]; //标记
  5. int next[][]={{,},{,},{,-},{-,}};
  6. int n,m; //实际地图行数、列数
  7. int endy,endx; //终点位置
  8. int min=;
  9.  
  10. /* run this program using the console pauser or add your own getch, system("pause") or input loop */
  11.  
  12. //构造一个盏来记录走迷宫的路径
  13. struct Node
  14. {
  15. int y;
  16. int x;
  17. };
  18.  
  19. struct Stack
  20. {
  21. Node * pbase;
  22. int top;
  23. };
  24.  
  25. void StackInit(Stack * pstack){
  26. pstack->pbase=new Node[];
  27. pstack->top=;
  28. }
  29.  
  30. void StackPush(Stack * pstack,int y,int x){
  31. Node node;
  32. node.y=y;
  33. node.x=x;
  34. pstack->pbase[pstack->top]=node;
  35. ++pstack->top;
  36. }
  37.  
  38. void StackCopy(Stack * pstack1,Stack * pstack2){
  39. pstack2->top=pstack1->top;
  40. for(int i=;i<pstack2->top;i++)
  41. {
  42. pstack2->pbase[i]=pstack1->pbase[i];
  43. }
  44. }
  45.  
  46. void StackPop(Stack * pstack){
  47. --pstack->top;
  48. }
  49.  
  50. Stack stack;
  51. Stack minstack;
  52.  
  53. //深度优先搜索
  54. void dfs(int y,int x,int step){
  55. int ty,tx;
  56. if(y==endy&&x==endx)
  57. {
  58. if(step<min)
  59. {
  60. StackCopy(&stack,&minstack);
  61. min=step;
  62. }
  63. return;
  64. }
  65.  
  66. for(int i=;i<;i++)
  67. {
  68. ty=y+next[i][];
  69. tx=x+next[i][];
  70. if(ty>=&&ty<n&&tx>=&&tx<m&&map[ty][tx]!='#'&&sign[ty][tx]==)
  71. {
  72. StackPush(&stack,ty,tx);
  73. sign[ty][tx]=;
  74. dfs(ty,tx,step+);
  75. StackPop(&stack);
  76. sign[ty][tx]=;
  77. }
  78. }
  79. return;
  80. }
  81.  
  82. int main(int argc, char** argv) {
  83. printf("请输入行数和列数:");
  84. scanf("%d%d",&n,&m);
  85. printf("请创建地图:\n");
  86. for(int i=;i<n;i++)
  87. {
  88. scanf("%s",&map[i]);
  89. }
  90. printf("创建的地图如下:\n");
  91. for(int i=;i<n;i++)
  92. {
  93. printf("%s\n",map[i]);
  94. }
  95. printf("请输入起点(y,x):");
  96. int starty,startx;
  97. scanf("%d%d",&starty,&startx);
  98. printf("请输入终点(y,x):");
  99. scanf("%d%d",&endy,&endx);
  100. sign[starty][startx]=;
  101.  
  102. StackInit(&stack);
  103. StackInit(&minstack);
  104.  
  105. dfs(starty,startx,);
  106. printf("最短路程为%d\n",min);
  107.  
  108. printf("最短路径为:\n");
  109. map[starty][startx]='s'; //用字符's'表示起点
  110. for(int i=;i<minstack.top;i++)
  111. {
  112. map[minstack.pbase[i].y][minstack.pbase[i].x]='>';
  113. }
  114. for(int i=;i<n;i++)
  115. {
  116. printf("%s\n",map[i]);
  117. }
  118. return ;
  119. }

深度优先搜索(DFS)的更多相关文章

  1. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  2. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  3. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

  4. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...

  5. 深度优先搜索 DFS 学习笔记

    深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ...

  6. 深度优先搜索(DFS)

    [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...

  7. 算法总结—深度优先搜索DFS

    深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈). 深度优先从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态. 1.poj2386 Lake C ...

  8. HDU(搜索专题) 1000 N皇后问题(深度优先搜索DFS)解题报告

    前几天一直在忙一些事情,所以一直没来得及开始这个搜索专题的训练,今天做了下这个专题的第一题,皇后问题在我没有开始接受Axie的算法低强度训练前,就早有耳闻了,但一直不知道是什么类型的题目,今天一看,原 ...

  9. [LeetCode OJ] Word Search 深度优先搜索DFS

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  10. 广度优先(bfs)和深度优先搜索(dfs)的应用实例

    广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ...

随机推荐

  1. 手机上的页面转换page slider

    小伙伴们是不是经常在手机上见到“转场"的情况,手机上的页面转换已经不像pc上整体的页面跳转,很多都是利用动画平滑地在页面之间的切换.   那么如何来做页面之间的转换呢?首先要明确的是,所谓的 ...

  2. 面向系统管理员的10款Linux GUI工具 (转自51cto)

    如果你是名系统管理员,现已到了Linux非知道不可的地步.如果你在更庞大的环境下工作,更是如此.许多企业组织已迁离了一切都借助点击式GUI来管理的Windows.幸好,Linux也有许多GUI工具可以 ...

  3. mysql开启慢查询

    linux下: 一.在mysql中查询是否开启了慢查询mysql>SHOW VARIABLES  LIKE '%slow%'; Variable_name     Valuelog_slow_q ...

  4. Java中的原始类型(Primitive Types)与引用类型(Reference Values)

    Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types). 与之对应,也存在有原始值(Primitive Values)和 ...

  5. 【axc】关于duplicate symbols for architecture x86_64错误的第三种可能及其解决办法

    今天分析一下duplicate symbols for architecture x86_64错误  也是困扰我一段时间   不过很幸运 在半个小时内找到了解决方案 百度上对于duplicate sy ...

  6. Requirejs之AMD规范

    一.什么是AMD规范 AMD是Asynchronous Module Definition-----异步模块定义 AMD规范定义了2个函数define()与require() 下面我们来看一下定义方法 ...

  7. 【译】在ASP.Net和IIS中删除不必要的HTTP响应头

    引入 每次当浏览器向Web服务器发起一个请求的时,都会伴随着一些HTTP头的发送.而这些HTTP头是用于给Web服务器提供一些额外信息以便于处理请求.比如说吧.如果浏览器支持压缩功能,则浏览器会发送A ...

  8. Qt字符串类——1.字符串常用的几种操作

    字符串有如下几个操作符: (1)QString提供了一个二元的"+"操作符用于组合两个字符串,并提供了一个"+="操作符用于将一个字符串追加到另一个字符串的末尾 ...

  9. inittab 分析

    内核初始化后,启动init进程/sbin/init,读取/etc/inittab文件进行初始化. 参考链接 http://wenku.baidu.com/view/5a82b5f67c1cfad619 ...

  10. Leetcode: Strong Password Checker

    A password is considered strong if below conditions are all met: It has at least 6 characters and at ...