图的深度优先搜索算法DFS

原创 2015年07月10日 16:51:14

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  time0
5  S←
6  for each vertex s V[G]
7       do if color[s] = WHITE
8       then   color[s] ← GRAY
9                   d[s] ← timetime +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] ← timetime +1
17          PUSH(S, v)
18                  else color[u] ← BLACK
19                          f [u] ← timetime +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应用——遍历有向图+判断有向图是否有圈

【0】README0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 “DFS应用——遍历有向图+判断有向图是否有圈” 的idea 并用源代码加以实现 ; 0.2) 判断有向图...
  • PacosonSWJTU
  • PacosonSWJTU
  • 2015年11月24日 09:56
  • 1107

DFS + 剪枝策略

一:简介 (1)相信做过ACM的人,都很熟悉图和树的深度优先搜索;算法里面有蛮力法 —— 就是暴力搜索(不加任何剪枝的搜索); (2)蛮力搜搜需要优化时,就是需要不停的剪枝,提前减少不必要的搜索路径,...
  • u010700335
  • u010700335
  • 2015年03月06日 09:29
  • 3847

深度优先搜索(DFS)

DFS   (深度优先搜索)   DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种。是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的...
  • ccDLlyy
  • ccDLlyy
  • 2016年10月03日 10:10
  • 884

深度优先搜索算法(DFS)

1. 深度优先搜索属于图的遍历算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。 2.搜索策略:...
  • u011898209
  • u011898209
  • 2013年11月22日 20:50
  • 460

深度优先搜索(DFS)详解

深度优先搜索是一种怎样的方法? 深度优先搜索所使用的策略就如其名字一样,只要可能,就在图中尽量的深入。深度优先搜素总是对最近才发现的结点v的出发边进行探索,直到该结点的所有出发边都被发现为止。一旦结点...
  • gu_solo
  • gu_solo
  • 2015年09月30日 16:14
  • 2945

DFS深度优先搜索(入门)

DFS入门(递归写法) 这两天在学习深度优先搜索(DFS),感觉DFS比BFS难,一开始主要是标记搞不清楚。DFS在回溯时要取消原先的标记,而BFS不存在回溯也就不存在取消标记这一问题。DFS可以用...
  • Coding_Or_Dead
  • Coding_Or_Dead
  • 2016年08月26日 11:06
  • 2987

深度优先搜索的实现

图的遍历是指从图中的某一个顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次。注意到树是一种特殊的图,所以树的遍历实际上也可以看作是一种特殊的图的遍历。图的遍历主要有两种算法:...
  • lisong694767315
  • lisong694767315
  • 2014年07月04日 16:06
  • 2384

深度理解基本图搜索算法

这篇随笔是在综合看了多本书,包括算法导论,人工智能等之后,写自己的一些感悟。 适合的读者:如果你已经能够思路清晰的回答以下问题,那么请直接忽略本文~ l A*,BFS,DFS算法的实现思路...
  • richie0006
  • richie0006
  • 2015年07月25日 09:25
  • 657

DFS与BFS的总结

BFS与DFS的讨论:BFS:这是一种基于队列这种数据结构的搜索方式,它的特点是由每一个状态可以扩展出许多状态,然后再以此扩展,直到找到目标状态或者队列中头尾指针相遇,即队列中所有状态都已处理完毕。 ...
  • zhouyusong
  • zhouyusong
  • 2014年12月06日 20:09
  • 811

深度优先搜索(DFS)-例题附思路-总结(一)

关于DFS的定义等基本的东西我就不说了~百度吧。 每个人的学习方法不一样,在我的学习中我是把DFS是分了类的,虽然总体思路是一样的,但是不同的应用环境就会应用不同的DFS模型,是的,模型。 下面我把目...
  • qq_32183461
  • qq_32183461
  • 2016年02月20日 20:16
  • 7384
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图的深度优先搜索算法DFS
举报原因:
原因补充:

(最多只允许输入30个字)