深度优先搜索DFS( 递归+非递归)

参考算法导论第三版 p349


/*
dfs搜索 - 邻接表
*/

#include <cstdio>
#include <vector>
#include <stack>
using std::vector;
using std::stack;


const int MAXN = 10;

struct Node
{
    int d;  //discovered 发现时间
    int f;  //finished 完成时间
    int parent; //前驱结点
    bool visit; //是否访问
};
Node node[MAXN];
int time = 0; // 模拟时间流逝
vector<vector<int>>g(MAXN);

void dfs_visit_1(int p) // recursion递归
{
    node[p].d = ++time; // 第一次的时间是1
    node[p].visit = true; // 已经访问过
    for (int i = 0; i < g[p].size(); ++i)
    {
        int temp = g[p][i];
        if (node[temp].visit == false)
        {
            node[temp].parent = p;
            dfs_visit_1(temp);
        }
    }
    node[p].f = ++time;
}

void dfs_visit_2(int p) // iteration 非递归,结果和递归的完全一样
{
    node[p].d = ++time; // 第一次的时间是1
    node[p].visit = true; // 已经访问过
    stack<int> stk;
    stk.push(p);
    while (!stk.empty())
    {
        int t = stk.top();
        int flag = true;
        for (int i = 0; i < g[t].size(); ++i)
        {
            int temp = g[t][i];
            if (node[temp].visit == false)
            {//每次取栈顶元素的邻接表的一个未访问的, 其余没访问的
			 //等下一次栈顶降到它时再从中选一个访问
                node[temp].d = ++time;
                node[temp].visit = true;
                node[temp].parent = t;
                stk.push(temp);
                flag = false;
                break;
            }
        }
        if (flag)
        {
            node[t].f = ++time;
            stk.pop();
        }
    }

}

void dfs(int N)
{
    for (int i = 1; i <= N; ++i) // 初始化
    {
        node[i].d = 0;
        node[i].f = 0;
        node[i].parent = 0;
        node[i].visit = false;
    }
    time = 0;
    for (int i = 1; i <= N; ++i) // 图可能不是连通的
    {
        if (node[i].visit == false)
        {
            dfs_visit_1(i); // 递归调用dfs_visit_1
            dfs_visit_2(i); // 迭代调用dfs_visit_2
        }
    }
}

void print(int N)
{
    for (int i = 1; i <= N; ++i)
    {
        printf("%d: d = %d, f = %d\n", i, node[i].d, node[i].f);
    }

}

int  main()
{
	freopen("F://input.txt", "r", stdin);
	int N, v, t;
	scanf("%d", &N);
	while (scanf("%d%d", &v, &t) != EOF)
	{
		g[v].push_back(t);//构造邻接表
	}
    dfs(N);
    print(N);
}

/*
测试数据: 算法导论 p351的图
6
1 2
1 3
3 2
2 4
4 3
5 4
5 6
6 6
*/













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值