1. 程式人生 > >深度優先搜尋DFS( 遞迴+非遞迴)

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













相關推薦

深度優先搜尋DFS( +)

參考演算法導論第三版 p349 /* dfs搜尋 - 鄰接表 */ #include <cstdio> #include <vector> #include <stack> using std::vector; using std::

演算法----圖的遍歷(深度優先搜尋DFS、廣度優先搜尋BFS)

圖的遍歷的定義:從圖的某個頂點出發訪問圖中所有的點,且每個頂點僅被訪問一次。 深度優先搜尋DFS: 準備:指定的起始點和終點,確定好當前點與鄰接點之間的偏移值、結束搜尋的條件、符合訪問的點所需條件、回溯處理; (1)若當前點的鄰接點有未被訪問的,則選一個進行訪問; (2)若當前點的鄰接點都不符合訪問條

深度優先搜尋DFS(洛谷)

ACM題集:https://blog.csdn.net/weixin_39778570/article/details/83187443 P1219 八皇后 題目:https://www.luogu.org/problemnew/show/P1219 題意:N皇后問題求解個數,部分輸出

C++資料結構 23 圖-深度優先搜尋(DFS)

還是按鄰接矩陣的圖,使用深度優先搜尋(DFS:使用堆疊)   #include <iostream> #include <stack> #define MAX_VERTS 20 using namespace std; /**使用鄰接矩陣來表示一個圖

三、【圖演算法】深度優先搜尋(DFS)

圖演算法是個龐大的家族,其中大部分成員的主體框架都可以歸結於圖的遍歷。圖的遍歷需要訪問所有頂點一次且僅 一次,此外,圖遍歷同時還要訪問所有的邊一次且僅一次。經過一次遍歷,樹邊的頂點共同構成了原圖的一顆遍歷樹。 為防止對頂點的重複訪問,在遍歷的過程中,需要動態地設定各頂點的不同狀態,並且隨著遍

寬度優先搜尋BFS 和深度優先搜尋DFS的比較。。

首先簡單介紹下題目。就是有9個掛鐘,時間只存在3,6,9,12 這4種狀態對應的 狀態編號是 1,2,3,0,然後給你9種操作時鐘的方式,每次可以事操作的時鐘狀態編號+1,如果編號到了4,就是表示為0。目標就是把9個鬧鐘全部變為0狀態。題目大致是這個意思,不懂的可以看看上

深度優先搜尋(DFS)與廣度優先搜尋(BFS)

深度優先搜尋的基本模型 void dfs(int step) { 判斷邊界 嘗試每一種可能 for(int i=0; i<n; i++) { 繼續下一步 dfs(step+1); } 返回 } 輸出一個

深度優先搜尋dfs之1到n的全排列(收藏)

/******** *給你一個數n,輸出1到n的全排列 *深度優先搜尋 ********/#include <stdio.h>#include <stdlib.h>int book[10], a[10], n;  void dfs(int step) 

藍橋杯 ADV-188 演算法提高 排列數(java) 深度優先搜尋 DFS

 演算法提高 排列數   時間限制:1.0s   記憶體限制:256.0MB 問題描述   0、1、2三個數字的全排列有六種,按照字母序排列如下:   012、021、102、120、201、210   輸入一個數n   求0~9十個數的全排列中的第n個(

深度優先搜尋(DFS)詳解

深度優先搜尋是一種怎樣的方法?深度優先搜尋所使用的策略就如其名字一樣,只要可能,就在圖中儘量的深入。深度優先搜素總是對最近才發現的結點v的出發邊進行探索,直到該結點的所有出發邊都被發現為止。一旦結點v的所有出發邊都被發現,搜尋則回溯到v的前驅結點(v是經過該點才被發現的),

leetcode 140. Word Break II 深度優先搜尋DFS + 很棒的動態規劃DP 做法 + 記錄前驅節點

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence

LeetCode演算法練習——深度優先搜尋 DFS

很久都沒有刷LeetCode了,上次LeetCode已經快是兩個月之前的事情了。現在繼續。之前中級演算法差不多刷完了,這次專練資料結構。這一篇主要是dfs題目,標識為簡單的題目一般就跳過了,主要刷中等與困難題。 LeetCode上分類為dfs的題目大多數與

深度優先搜尋DFS C++實現

使用鄰接矩陣+棧的形式實現深度優先搜尋,棧中儲存訪問過的節點,後進先出的結構可以讓他回退搜尋未訪問過的節點。//DFS,使用 鄰接矩陣+棧 實現 #include <iostream> #include <stack> using namespace

演算法: 無向圖的深度優先搜尋(dfs)和廣度優先搜尋(bfs)

更新:DFS和BFS是應用廣泛而實現簡便的演算法,但有2個小點需要稍稍注意一下。 對於DFS來說,可以用遞迴,也可以用迭代。對於一張較大的圖,迭代是優於遞迴的,因為遞迴要維護一個函式呼叫棧。小心stackoverflow喔。 對於BFS來說,實現起來需要注意

實現深度優先搜尋DFS(以迷宮解救為例子)

演算法描述:給定開始點座標(x,y) 和終點座標(p,q),在一個二維數組裡面,其中1代表障礙物,0則沒有。求開始到終點的最短距離。 程式碼如下: MIN = 9999999 a = [[0

深度優先搜尋DFS——圖鄰接表表示

作為圖的一個基本演算法,DFS應用很廣,可以推廣出很多實用的演算法。下面貼出一個比較常用的用鄰接表表示的圖DFS。 /* 圖鄰接表表示DFS input: 1 7 A 1 5 B 2 4 3 C 2 4 2 D 3 6 5 2 E 3 7 4 1 F 1 4 G 1 5

圖的基本演算法--深度優先搜尋(dfs) 和 廣度優先搜尋(bfs)

# 圖 # 0 # / | \ # 1 2 - 4 # / # 3 m = 999999 # 代表沒有連線 a =

DFS深度優先搜尋)的實現

突然想起來搜尋是屬於圖論的,那麼在解決圖論的過程中把搜尋解決掉。沒想到非遞迴實現一下就搞了兩天。雖然有些疑問還沒有解決,但感覺已經可以寫總結了,與其說總結,不如說一次嘗試的記錄(因為有個題最後還是TLE嘛)。(求規範程式碼!!!@嘯爺) 眾所周知,DFS的常規寫法是遞迴實現,但遞迴普遍慢所以可

深度優先搜尋DFS實現邏輯詳解

 遞迴與非遞迴:        資料結構對於學習程式設計的人來說是非常重要的,我們在現實生活碰到的各種煩難問題可以用遞迴來實現,一個遞迴思想就把問題給簡單化了,但是我們都知道遞迴是非常耗時的,一旦資料量龐大起來,遞迴

DFS深度優先搜尋樹) 實現

一、鄰接矩陣 1、遞迴 有限制條件,如果不是連通圖,那麼找不完,必須要用for遍歷每個頂點 思想:從指定的v頂點出發,訪問他,標記為已經訪問。然後,尋找跟這個v頂點連線的每一條邊(for迴圈),如果滿足有邊+未被訪問,則遞迴呼叫 //矩陣的深度遞迴搜