1.问题描写叙述与理解

深度优先搜索(Depth First Search。DFS)所遵循的策略。如同其名称所云。是在图中尽可能“更深”地进行搜索。

在深度优先搜索中,对最新发现的顶点v若此顶点尚有未探索过从其出发的边就探索之。

当v的全部边都被探索过。搜索“回溯”到从其出发发现顶点v的顶点。此过程继续直至发现全部从源点可达的顶点。若图中还有未发现的顶点,则以当中之中的一个为新的源点反复搜索。直至全部的顶点都被发现。与BFS中源顶点是指定的稍有不同。 DFS搜索轨迹Gπ将形成一片森林—— 深度优先森林。

在深度优先搜索过程中对每个顶点u跟踪两个时间:发现时间d[u]和完毕时间f [u]。d[u]记录首次发现(u由白色变成灰色)时刻,f [u]记录完毕v的邻接表检測(变成黑色)时刻。

输入:图G=<V,E>。

输出:G的深度优先森林Gπ以及图中各顶点在搜索过程中的发现时间和完毕时间。

  1. 算法伪代码
  1. DFS(G)
  2. 1 for each vertex uV[G]
  3. 2 do color[u]←WHITE
  4. 3 [u] NIL
  5. 4 time 0
  6. 5 S←
  7. 6 for each vertex s V[G]
  8. 7 do if color[s] = WHITE
  9. 8 then color[s] GRAY
  10. 9 d[s] time time +1
  11. 10 PUSH(S, s)
  12. 11 while S≠
  13. 12 do uTOP(S)
  14. 13 if v Adj[u] and color[v] = WHITE
  15. 14 then color[v] GRAY
  16. 15 [v] u
  17. 16 d[v] time time +1
  18. 17 PUSH(S, v)
  19. 18 else color[u] BLACK
  20. 19 f [u] time time +1
  21. 20 POP(S)
  22. 21 return d, f, and

DFS施于一个有向图的过程

3.程序实现

  1. /***********************************
  2. *@file:graph.h
  3. *@ brif:图的邻接表的算法实现类
  4. *@ author:sf
  5. *@data:20150704
  6. *@version 1.0
  7. *
  8. ************************************/
  9. #ifndef _GRAPH_H
  10. #define _GRAPH_H
  11. #include <list>
  12. using namespace std;
  13. struct vertex//邻接表节点结构
  14. {
  15. double weight;//边的权值
  16. int index;//邻接顶点
  17. };
  18. class Graph
  19. {
  20. public:
  21. list<vertex> *adj;//邻接表数组
  22. int n;//顶点个数
  23. Graph(double *a,int n);
  24. ~Graph();
  25. };
  26. #endif // _GRAPH_H
  1. #include "stdafx.h"
  2. #include "Graph.h"
  3. Graph::Graph(float *a,int n):n(n)//a是图的邻接矩阵
  4. {
  5. adj = new list<vertex>[n];
  6. for (int i = 0; i < n;i++)//对每个顶点i
  7. for (int j = 0; j < n;j++)
  8. if (a[i*n+j]!=0.0)
  9. {
  10. vertex node = { a[i*n + j], j };//a[i,j]=weight 边的权重 j,邻接节点号
  11. adj[i].push_back(node);
  12. }
  13. }
  14. Graph::~Graph()
  15. {
  16. delete[] adj;
  17. adj = NULL;
  18. }
  1. #ifndef _DFS_H
  2. #define _DFS_H
  3. /***********************************
  4. *@file:dfs.h
  5. *@ brif:深度优先搜索算法实现
  6. *@ author:sf
  7. *@data:20150708
  8. *@version 1.0
  9. *
  10. ************************************/
  11. #include "Graph.h"
  12. #include <stack>
  13. struct Parameter3
  14. {
  15. int* first;
  16. int* second;
  17. int* third;
  18. };
  19. /***********************************
  20. *@function:dfs
  21. *@ brif:图的邻接表的图的深度优先搜索(Depth First Search, DFS)算法实现
  22. *@ input param: g 图的邻接表
  23. *@ output param: pi g的深度优先森林 d :发现时间 f:完毕时间
  24. *@ author:sf
  25. *@data:20150708
  26. *@version 1.0
  27. *
  28. ************************************/
  29. Parameter3 dfs(const Graph& g);
  30. #endif
  1. #include "dfs.h"
  2. enum vertex_color{WHITE,GRAY,BLACK};
  3. typedef enum vertex_color Color;
  4. Parameter3 dfs(const Graph& g)
  5. {
  6. int n = g.n, u, v, s;
  7. Color *color = new Color[n];
  8. int *pi = new int[n], *d = new int[n], *f = new int[n], time = 0;
  9. fill(pi, pi + n, -1);
  10. fill(color, color + n, WHITE);
  11. stack<int> S;//栈
  12. list<vertex>::iterator *pos = new list<vertex>::iterator[n];
  13. for (u = 0; u < n; ++u)
  14. pos[u] = g.adj->begin();
  15. for (s = 0; s < n;++s)
  16. {
  17. if (color[s]==WHITE)//以顶点s为根创建一颗深度优先树
  18. {
  19. color[s] = GRAY;
  20. d[s] = ++time;
  21. S.push(s);
  22. while (!S.empty())
  23. {
  24. u = s = S.top();
  25. list<vertex>::iterator p;
  26. p = pos[u];
  27. while ( g.adj[n].end()!=p )
  28. //眼下程序有些问题,在訪问这个末尾迭代器是出错,眼下还没有解决
  29. {
  30. v = (*p).index;
  31. if (color[v] == WHITE)
  32. break;
  33. else
  34. ++p;//u的邻接点中找尚存在的未发现点
  35. }
  36. pos[u] = p;
  37. if (pos[u] != g.adj[n].end())//找到白色顶点将其压入栈
  38. {
  39. color[v] = GRAY;
  40. d[v] = ++time;
  41. pi[v] = u;
  42. S.push(v);
  43. }
  44. else//否则完毕对u的訪问
  45. {
  46. color[u] = BLACK;
  47. f[u] = ++time;
  48. S.pop();
  49. pos[u] = g.adj[n].begin();
  50. }
  51. }
  52. }
  53. }
  54. delete[]color; delete[]pos;
  55. Parameter3 reParams;
  56. reParams.first = pi;
  57. reParams.second = d;
  58. reParams.third = f;
  59. return reParams;
  60. }
  1. // DFS.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "dfs.h"
  5. #include "Graph.h"
  6. #include <iostream>
  7. using namespace std;
  8. int _tmain(int argc, _TCHAR* argv[])
  9. {
  10. int s = 1, n = 8;
  11. Parameter3 ret;
  12. double a[] =
  13. {
  14. 0, 1, 0, 0, 1, 1,
  15. 1, 0, 0, 0, 0, 1,
  16. 0, 0, 0, 1, 0, 1,
  17. 0, 0, 1, 0, 0, 1,
  18. 1, 0, 0, 0, 0, 1,
  19. 1, 1, 1, 1, 1, 0
  20. };
  21. Graph g(a, 6);
  22. ret = dfs(g);
  23. for (int i = 0; i < 6; ++i)
  24. {
  25. if (i != s)
  26. {
  27. cout << i << ";" << "parent " << ret.first[i];
  28. cout << " discover/finish: " << ret.second[i]<<"/"<<ret.third[i] << endl;
  29. }
  30. }
  31. system("pause");
  32. return (EXIT_SUCCESS);
  33. }

图的深度优先搜索算法DFS的更多相关文章

  1. 图的深度优先遍历DFS

    图的深度优先遍历是树的前序遍历的应用,其实就是一个递归的过程,我们人为的规定一种条件,或者说一种继续遍历下去的判断条件,只要满足我们定义的这种条件,我们就遍历下去,当然,走过的节点必须记录下来,当条件 ...

  2. 图的深度优先遍历(DFS)—递归算法

    实验环境:win10, DEV C++5.11 实验要求: 实现图的深度优先遍历 实验代码: #include <iostream> #define maxSize 255 #includ ...

  3. 图的深度优先遍历(DFS)和广度优先遍历(BFS)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  4. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  5. 图的深度优先搜索dfs

    图的深度优先搜索: 1.将最初访问的顶点压入栈: 2.只要栈中仍有顶点,就循环进行下述操作: (1)访问栈顶部的顶点u: (2)从当前访问的顶点u 移动至顶点v 时,将v 压入栈.如果当前顶点u 不存 ...

  6. 图的深度优先遍历(DFS) c++ 非递归实现

    深搜算法对于程序员来讲是必会的基础,不仅要会,更要熟练.ACM竞赛中,深搜也牢牢占据着很重要的一部分.本文用显式栈(非递归)实现了图的深度优先遍历,希望大家可以相互学习. 栈实现的基本思路是将一个节点 ...

  7. 【C++】基于邻接矩阵的图的深度优先遍历(DFS)和广度优先遍历(BFS)

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  8. 图的深度优先遍历(DFS)和广度优先遍历(BFS)算法分析

    1. 深度优先遍历 深度优先遍历(Depth First Search)的主要思想是: 1.首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点: 2.当没有未访问过的顶点时,则回 ...

  9. 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...

随机推荐

  1. Ios 程序封装,安装流程

    转:http://www.myexception.cn/operating-system/1436560.html Ios 程序打包,安装流程 一.发布测试,是指将你的程序给   * 你的测试人员,因 ...

  2. PHP $_SERVER的详细参数及说明

    $_SERVER['PHP_SELF']#当前正在执行脚本的文件名,与documentroot相关. $_SERVER['argv']#传递给该脚本的参数. $_SERVER['argc']#包含传递 ...

  3. <转>亲手缔造DNS体系,创建DNS私有根:DNS系列之六

    打造DNS私有根 我们现在已经从前面的博文中了解到了很多DNS的相关知识,今天我们用一个综合性的实验把前面的内容都串起来复习一下,这个有趣的实验就是DNS的私有根.私有根顾名思义是由个人或企业自行创建 ...

  4. 重读gets()与is函数的用法

    这是从百度百科上查找的资料: gets(): 从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中.换行符不作为读取串的内容,读取的换行符 ...

  5. angularjs ng-class 两种用法

    ng-class="{'active':current.actived_tree==item}" ng-class="{true:'label-danger white- ...

  6. JavaScript如何判断参数为浮点型

    在codewars里,确实可以学到很多很酷的方法,例如这一次的题目是判断数字是否为浮点型.我一开始是想有没有原生的js方法,像isNaN(),isFinite(),在前者Infinity是不属于NaN ...

  7. POJ 3660 Cow Contest (最短路dijkstra)

    MPI Maelstrom 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/G Description BIT has recen ...

  8. qemu 模拟-arm-mini2440开发板-启动u-boot,kernel和nfs文件系统

    qemu 本文介绍了如何编译u-boot.linux kernel,然后用qemu启动u-boot和linux kernel,达到与开发板上一样的学习效果! 虽然已经买了2440开发板,但是在实际学习 ...

  9. How to organize the Template Files in C++

    Normally you put class definitions in a header file and method definitions in a source file. Code th ...

  10. WordPress主题制作教程[壹] - 了解WP&结构&索引

    最近开始筹备WordPress主题开发了.首先我们在此章节中进行了解什么是WP,以及WP的结构.通过这个文章索引到以后所写的WP系列教程. (抱歉,大家不要急,持续更新中....) 1.首先,我们来认 ...