【转载】深度优先搜索代码

 

本文章代码中的图用邻接矩阵来表示,所以算法复杂度为O(V^2)。如果用邻接表来表示,那么算法的复杂度为O(V+E)。

DFS可用来判断图中是否有环,展现无向图中的连通分支。
通过DFS,形成一个由多棵深度优先树所组成的深度优先森林。将原先图中的边添加到该森林之后,可以将所有边定义为以下四类:
1.    树边:森林中自带的边(即不在森林生成后,从原先图中添加的边)。
2.    反向边:从某个节点指向祖先的边,包括自己指向自己。非森林自带的边。如果图中存在反向边,则表明存在环。
3.    正向边:从某个节点指向后代的边,非森林自带的边。
4.    交叉边:边的两端点之间没有祖先后代关系,非森林自带的边。

 


 

在DFS过程中,可以对任意两点间的边进行分类,对于有向图和无向图,分类情况有所区别。
有向图:
1.    树边:当visit了节点u后,如果边(u, v)存在,且v为WHITE,则该边为树边。
2.    反向边:当visit了节点u后,如果边(u, v)存在,且v为GREY,则该边位反向边。
3.    正向边:当visit了节点u后,如果边(u, v)存在,且v为BLACK,StartTime[u] < StartTime[v] < EndTime[v] < EndTime[u],则边为正向边。
4.    交叉边:当visit了节点u后,如果边(u, v)存在,且v为BLACK,StartTime[v] < EndTime[v] < StartTime[u] < EndTime[u],则边为交叉边。

 

无向图:
1.    树边:当visit了节点u后,如果边(u, v)存在,且v为WHITE,则该边为树边。
2.    反向边:否则就是反向边。


 

代码

#include <iostream>
#define MAXLENGTH 1000
#define WHITE 0
#define GREY 1
#define BLACK 2
using namespace std;
//The color of node. They can be used to define the link type between two nodes. WHITE means the node has not been visited. Gray means the node has been searched but its descendants have not been not all visited. Black means that the node and its descendants have all been visited.
int Color[MAXLENGTH];
//the parent of node i
int Parent[MAXLENGTH];
//the first time to be visited
int StartTime[MAXLENGTH];
//the second time to be visited, after visiting the descendants.
int EndTime[MAXLENGTH];
//the node graph
bool Graph[MAXLENGTH][MAXLENGTH];
//count the time
int time_count;
void DFS_Visit(int, int, int);
/**
 * @brief Dfs graph who has n nodes
 *
 * @param n: the nodes' number
 */
void DFS(int n)
{
    //initialization
    for (int i = 0; i < n; ++i)
    {
        Color[i] = WHITE;
    }
    time_count = 0;
    //start DFS visit. Some nodes may can't be visited if starts from some nodes, so loop to ensure that every node can be visited.
    for (int i = 0; i < n; ++i)
    {
        if (Color[i] == WHITE)
        {
            DFS_Visit(i, -1, n);
        }
    }
}
/**
 * @brief DFS visit node
 *
 * @param node: the node to be visited
 * @param parent: the parent of the node
 * @param n: the nodes number in the graph
 */
void DFS_Visit(int node, int parent, int n)
{
    Color[node] = GREY;
    Parent[node] = parent;
    StartTime[node] = time_count++;
    for (int i = 0; i < n; ++i)
    {
        if (Graph[node][i] && Color[i] == WHITE)
        {
            DFS_Visit(i, node, n);
        }
    }
    Color[node] = BLACK;
    EndTime[node] = time_count++;
}
/**
 * @brief Print the path from start to end
 *
 * @param end: the end node
 */
void PrintPath(int end)
{
    cout << "Show path from end to start" << endl;
    while (end != -1)
    {
        cout << end << " start-time:" << StartTime[end] << "   end-time:" << EndTime[end] << endl;
        end = Parent[end];
    }
}
int main()
{
    int n;
    while (cin >> n, n != 0)
    {
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                cin >> Graph[i][j];
            }
        }
        int end;
        DFS(n);
        while (cout << "Input the end node, -1 means no more search." << endl, cin >> end, end != -1)
        {
            PrintPath(end);
        }
    }
}

 

posted @ 2014-09-19 17:09  hansongjiang8  阅读(446)  评论(0编辑  收藏  举报