深度優先搜索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
*/













發佈了62 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章