dfs非遞歸java(DFS非遞歸算法)

本文目錄一覽:

DFS 遞歸為什麼比非遞歸要快???

非遞歸肯定要快一些,遞歸的話需要不斷的調用自己的函數原型,每調用一次都需要增長棧來存儲變量,而且返回前還需要將當前結果寫入在返回地址中,對內存使用效率極低。

設計一個基於深度優先遍歷的算法,判斷一個給定的有向圖是否包含迴路。

你好,關於DFS判斷有向圖是否存在迴路的問題,我本人編寫的考研資料中有相關的原創總結,希望對你有幫助,轉載還請註明原創出處:《大連理工大學軟件學院887專業課(2021版)》。如有問題可以加我QQ601964408交流。

法一:利用遞歸方式,在DFS對圖進行遍歷時,將遍歷過的頂點放入棧中,如果新遍歷的頂點已經存在於遞歸棧中,則說明存在一個反向邊,即存在一個環。此時棧中結點剛好是環路中的所有結點!

注意該方法沒辦法用DFS的非遞歸方法實現,因為非遞歸方法中,利用出棧的結點獲取下一個鄰接點入棧,和遞歸方式不同的地方在於,即使圖中有環,非遞歸方法中的棧也無法存儲環上的結點。(DFS的非遞歸詳見本小結後續的代碼總結部分)

代碼實現如下:

void HasCycle ( Graph G ) {

bool visited [MAX_VERTEX_NUM] ; //訪問標記數組

bool recursionStack [MAX_VERTEX_NUM] ; //標記該點是否在棧中

for ( i=0 ; iG.vexnum ; i++) {

//mark all the vertices as not visited and not part of recursion stack

//標記所有結點均未訪問以及不在棧中

visited [i] = FALSE ;

recursionStack [i] = FALSE ;

}

//call the recursive helper function to detect cycle in different DFS trees

//調用輔助遞歸函數以檢測不同DFS樹種的環路

for ( int i =0 ; i G.vexnum ; i++ ) //每次檢測一個連通圖

if ( CheckCyclic ( G , i , VISITED , recursionStack ) ) ;

return true ; //存在迴路

return false ; //不存在迴路

}

bool CheckCyclic ( Graph G , int v , bool [ ] visited , bool [ ] recursionStack ) {

if ( visited [v] == FALSE) {

//mark the current nodes as visited and part of recursion stack

//將當前結點的標記數組和遞歸棧標記,置為已訪問

visited [v] = TRUE ;

recursionStack [v] = TRUE ;

//recursion for all the vertices adjacent to this vertex

//遞歸該頂點附近的所有頂點

for ( Edge e = G.FirstEdge(v) ; G.IsEdge(e) ; e=G.NextEdge(e) ) {

//判斷下一結點未被訪問,進入遞歸函數判斷是否有環

if ( visited [G.ToVertex(e) ] == FALSE

CheckCyclic ( G , G.ToVertex(e) , visited , recursionStack) )

return TRUE ;

//當下一結點已經訪問過,並且已經在棧中,判斷有環

else if ( recusionStack (G.ToVertex(e) ) == TRUE )

return TRUE ;

}//end_for

}//end_if

//remove the vertex from recursion stack

//從遞歸棧種移除該結點

recursionStack [v] = FALSE ;

return false ; //判斷無環

}

————————————————————————————————–

法二:本方法與法一非常相似,方法一中存在三種情況,還未入棧時表示未被訪問過的點;在棧中時表示已經被訪問過但是還沒有遞歸結束;從棧中出棧時表示遞歸結束,即後代也全部被訪問過了。上述三種情況分別用 -1,0,1三種狀態來標記點。

針對上述思路,假設正在處理點v,那麼v的狀態是0,其餘正在處理的結點的狀態也是0,如果從狀態0的結點遍歷到狀態為0的結點,那麼就存在環。此時所有狀態為0的結點構成了一個環!發現存在環時遍歷輸出state數組即可,不過該方法輸出時不是按照環路的順序輸出;如果需要順序輸出環路,可增加一個cycle數組,每次記錄環路的起點位置i。用cycle[i]記錄結點i的下一個結點編號。利用遞歸的方式輸出cycle數組即可得到迴路順序。

代碼實現:

bool Found = FALSE ; //標記是否發現環路

void HasCycle ( Graph G ) {

int state [MAX_VERTEX_NUM] ; //結點狀態標識數組

for ( i=0 ; iG.vexnum ; i++) {

state [i] = -1 ;

}

for ( int i =0 ; i G.vexnum ; i++ ) { //每次檢測一個連通圖

CheckCyclic ( G , i , state );

if ( Found == TRUE ) ; //存在迴路

return true ;

}

return false ; //不存在迴路

}

void CheckCyclic ( Graph G , int v , int [ ] state ) {

if ( state [v] == -1) { //如果未訪問過

state [v] = 0 ; //改變該點的狀態

for ( Edge e = G.FirstEdge(v) ; G.IsEdge(e) ; e=G.NextEdge(e) ) {

if ( state [ G.ToVertex(e) ] == -1 )

CheckCyclic ( G , G.ToVertex(e) , state )

else if ( state [ G.ToVertex(e) ] == 0 ) //該圖有環

Found = TRUE ;

}//end_for

}//end_if

state [v] = 1 ; //該點遞歸結束,即後代也訪問完

}

如何將回溯法dfs改寫為非遞歸的

我的印象中貌似回溯法本身就是基於dfs的算法,俗稱爆搜?

可以寫人工棧,但是如果在競賽中的話寫人工棧意義不大,Linux下本身就有80W左右的棧空間,而且人工棧不見得就比系統的快。

人工棧的原理非常簡單,就是開若干個數組,每個數組對應開一個指針t,把原來dfs中每一層的信息都記錄到數組裡,dfs改成循環,如while (t!=0) ,要進入一層時t++,當退出一層時t–即可。

數據結構圖的遍歷 1)先任意創建一個圖; 2)圖的DFS,BFS的遞歸和非遞歸算法的實現 3)要求用有向圖和無向圖

//DFS,無向圖+有向圖,鄰接矩陣實現。

//你的東西太多了。一個一個問吧。而且200分太少了。你這麼多種情況。至少也得寫8種吧。

#include string

#include string.h

#include stdio.h

#include vector

#include iostream

#include set

#include math.h

#include map

#include algorithm

#include queue

using namespace std;

const int MAX=210000;

int mat[10][10];

bool vis[10]={false};

void DFS(int s,int n)

{

int i;

vis[s]=true;

printf(“%d “,s);

for(i=0;in;i++)

{

if(mat[s][i]!vis[i])

{

DFS(i,n);

}

}

}

int main()

{   

int i,n;

int j;

n=10;

for(i=0;in;i++)

{

for(j=0;jn;j++)

mat[i][j]=1;

}

DFS(0,n);

    return 0;

/*

*/

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/283620.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-22 08:08
下一篇 2024-12-22 08:08

相關推薦

  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 數據結構與算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序算法、字符串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • 台階走法遞歸

    台階走法遞歸是一個經典的遞歸問題,在計算機算法中有着廣泛的應用。本篇文章將從遞歸的思想出發,詳細分析如何解決這個問題。 一、遞歸基礎知識 遞歸是指一個函數直接或間接地調用自身。遞歸…

    編程 2025-04-29
  • 神經網絡BP算法原理

    本文將從多個方面對神經網絡BP算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP算法簡介 BP算法是一種常用的神經網絡訓練算法,其全稱為反向傳播算法。BP算法的基本思想是通過正…

    編程 2025-04-29
  • MySQL遞歸函數的用法

    本文將從多個方面對MySQL遞歸函數的用法做詳細的闡述,包括函數的定義、使用方法、示例及注意事項。 一、遞歸函數的定義 遞歸函數是指在函數內部調用自身的函數。MySQL提供了CRE…

    編程 2025-04-29
  • 粒子群算法Python的介紹和實現

    本文將介紹粒子群算法的原理和Python實現方法,將從以下幾個方面進行詳細闡述。 一、粒子群算法的原理 粒子群算法(Particle Swarm Optimization, PSO…

    編程 2025-04-29

發表回復

登錄後才能評論