您的位置:首页 > 其它

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

2014-10-31 20:30 585 查看
参考算法导论第三版 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
*/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: