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

DFS施于一个有向图的过程

3.程序实现

/***********************************
*@file:graph.h
*@ brif:图的邻接表的算法实现类
*@ author:sf
*@data:20150704
*@version 1.0
*
************************************/
#ifndef _GRAPH_H
#define _GRAPH_H #include <list>
using namespace std;
struct vertex//邻接表节点结构
{
double weight;//边的权值
int index;//邻接顶点
};
class Graph
{
public:
list<vertex> *adj;//邻接表数组
int n;//顶点个数
Graph(double *a,int n);
~Graph(); }; #endif // _GRAPH_H
#include "stdafx.h"
#include "Graph.h" Graph::Graph(float *a,int n):n(n)//a是图的邻接矩阵
{
adj = new list<vertex>[n];
for (int i = 0; i < n;i++)//对每个顶点i
for (int j = 0; j < n;j++)
if (a[i*n+j]!=0.0)
{
vertex node = { a[i*n + j], j };//a[i,j]=weight 边的权重 j,邻接节点号
adj[i].push_back(node);
}
}
Graph::~Graph()
{
delete[] adj;
adj = NULL;
}
#ifndef _DFS_H
#define _DFS_H
/***********************************
*@file:dfs.h
*@ brif:深度优先搜索算法实现
*@ author:sf
*@data:20150708
*@version 1.0
*
************************************/
#include "Graph.h"
#include <stack>
struct Parameter3
{
int* first;
int* second;
int* third;
};
/***********************************
*@function:dfs
*@ brif:图的邻接表的图的深度优先搜索(Depth First Search, DFS)算法实现
*@ input param: g 图的邻接表
*@ output param: pi g的深度优先森林 d :发现时间 f:完毕时间
*@ author:sf
*@data:20150708
*@version 1.0
*
************************************/
Parameter3 dfs(const Graph& g);
#endif
#include "dfs.h"
enum vertex_color{WHITE,GRAY,BLACK};
typedef enum vertex_color Color;
Parameter3 dfs(const Graph& g)
{
int n = g.n, u, v, s;
Color *color = new Color[n];
int *pi = new int[n], *d = new int[n], *f = new int[n], time = 0;
fill(pi, pi + n, -1);
fill(color, color + n, WHITE);
stack<int> S;//栈
list<vertex>::iterator *pos = new list<vertex>::iterator[n];
for (u = 0; u < n; ++u)
pos[u] = g.adj->begin();
for (s = 0; s < n;++s)
{
if (color[s]==WHITE)//以顶点s为根创建一颗深度优先树
{
color[s] = GRAY;
d[s] = ++time;
S.push(s);
while (!S.empty())
{
u = s = S.top();
list<vertex>::iterator p;
p = pos[u];
while ( g.adj[n].end()!=p )
//眼下程序有些问题,在訪问这个末尾迭代器是出错,眼下还没有解决
{
v = (*p).index;
if (color[v] == WHITE)
break;
else
++p;//u的邻接点中找尚存在的未发现点
}
pos[u] = p;
if (pos[u] != g.adj[n].end())//找到白色顶点将其压入栈
{
color[v] = GRAY;
d[v] = ++time;
pi[v] = u;
S.push(v);
}
else//否则完毕对u的訪问
{
color[u] = BLACK;
f[u] = ++time;
S.pop();
pos[u] = g.adj[n].begin();
}
}
}
}
delete[]color; delete[]pos;
Parameter3 reParams;
reParams.first = pi;
reParams.second = d;
reParams.third = f;
return reParams;
}
// DFS.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"
#include "dfs.h"
#include "Graph.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int s = 1, n = 8;
Parameter3 ret;
double a[] =
{
0, 1, 0, 0, 1, 1,
1, 0, 0, 0, 0, 1,
0, 0, 0, 1, 0, 1,
0, 0, 1, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 0
};
Graph g(a, 6);
ret = dfs(g);
for (int i = 0; i < 6; ++i)
{
if (i != s)
{
cout << i << ";" << "parent " << ret.first[i];
cout << " discover/finish: " << ret.second[i]<<"/"<<ret.third[i] << endl;
}
}
system("pause");
return (EXIT_SUCCESS);
}

图的深度优先搜索算法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. 也说Autofac在MVC的简单实践:破解在Controller构造函数中的实例化 - winhu

    相信大家对Autofac并不陌生,很多人都在使用.本文只是介绍一下本人在使用时的一点想法总结. 在使用一个框架时,肯定要去它的官网查阅一下.autofac的官网给出了一些经典的使用案例.如注册容器: ...

  2. 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?

    题目:给定一个函数rand()能产生1到n之间的等概率随机数,问如何产生1到m之间等概率的随机数? 先把问题特殊化,例如原题变为给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一 ...

  3. Ubuntu消息菜单(MessagingMenu)API

    应用程序可以注册在消息菜单里显示消息,它也可以使用全局聊天状态项目. 注册 应用程序要在消息菜单里显示消息,必须满足以下条件: $HOME/.config/indicators/messages/ap ...

  4. 通过ListActivity使用ListView布局方法

    先简单的介绍一下ListActivity ListActivity是一个专门显示ListView的Activity类,它内置了ListView对象,只要我们设置了数据源,就会自动地显示出来.ListA ...

  5. C# Adding Hyperlink to Windows Form z

    When creating a Windows form in C#, we would like to create a hyperlink so that when the user click ...

  6. Tour

    题意: 给n个点的坐标,求形成的最短的闭合回路. 分析: 经典问题,dp[i][j]表示有1-i点再由j回到1点的最短距离,i点有两种情况,在去的路径上 dp[i][j]=min(dp[i][j],d ...

  7. Tableau学习笔记之五

    计算用户自定义字段,虽然在Tableau软件中已经加入了很多的数值操作运算,比如平均值,最大值等,但是可以自定义自己需要的数值操作运算. 数值操作可以有以下:预定义函数,百分比,总计,分级等等 1.直 ...

  8. C++实现网格水印之调试笔记(六)——补充

    调用matlab生成的网格水印特征向量矩阵 从文件中读取的原始网格的特征向量矩阵 好吧,之前得出的结果不正确是因为代码写错了.因为实现论文中的提取方案时代码写错了,自己想了另外一个方法,结果方向两者在 ...

  9. SQL对字符串进行排序

    假设字符串中只由'A'.'B'.'C'.'D'组成,且长度为7.并设函数REPLICATE(<字符串>,<n>)可以创建一个<字符串>的n个副本的字符串,另外还有R ...

  10. 【九度OJ】题目1009-二叉搜索树

    题目 思路 构建二叉搜索树,并保存先序遍历和中序遍历的序列在samplePreOrder,sampleInOrder 每遇到一个新的序列,构建一棵二叉搜索树,保存先序遍历和中序遍历的序列testPre ...