1. 程式人生 > >圖的深度優先遍歷(非遞迴+遞迴,詳解)

圖的深度優先遍歷(非遞迴+遞迴,詳解)

圖的深度優先遍歷

這裡寫圖片描述

非遞迴演算法:

#include<iostream>
#include<stack>
using namespace std;
const int MaxSize=100;
class MGraph{//鄰接矩陣的構建 
    public:
        int adj[MaxSize][MaxSize],visited[MaxSize];
        int adjvexNum,arcNum;
        MGraph(int n,int e);
}; 
MGraph::MGraph(int n,int e){
    adjvexNum=n;//頂點數 
arcNum=e;//邊數 int v1,v2; for(int i=0;i<adjvexNum;i++) for(int j=0;j<adjvexNum;j++) adj[i][j]=0;//初始化,0意味兩個頂點沒有連線 for(int i=0;i<adjvexNum;i++) visited[i]=0;//初始化,0意味該頂點沒有訪問 for(int i=0;i<arcNum;i++){ cin>>v1>>v2; adj[v1][v2]=1;//這裡因為圖是無向的,所以兩者都為1
adj[v2][v1]=1;//若是有向的,這個不需要為1 } } void DFS(int i,MGraph G){ stack<int> s;//定義一個棧 s.push(i);//首先把頂點進棧 cout<<s.top()<<" ";//輸出 int t=i; G.visited[i]=1;//該頂點已經被訪問,vistied[i]=1 for(int j=i;;j++){ if(G.adj[i][j]==1&&G.visited[j]==0){//出現於i的鄰接點
G.visited[j]=1; s.push(j);//j入棧 cout<<s.top()<<" "; i=j;j=0;//為了查詢j的鄰接點 } if(j==G.adjvexNum){//意味找不到i的鄰接點 if(t==s.top())//若棧內的top()頂點和最開始的i相同,意味遍歷結束! break; s.pop(); //該頂點出棧 i=s.top();j=0;// 以剩下的棧內top()為i,查詢i的鄰接點 } } } int main(){ int adjvexNum,arcNum; cout<<"輸入頂點數和邊數:"<<endl; cin>>adjvexNum>>arcNum; MGraph G(adjvexNum,arcNum);//構造圖 DFS(0,G); return 0; }

遞迴演算法:

#include<iostream>
#include<stack>
using namespace std;
const int MaxSize=100;
class MGraph{
    public:
        int adj[MaxSize][MaxSize],visited[MaxSize];
        int adjvexNum,arcNum;
        MGraph(int n,int e);
}; 
MGraph::MGraph(int n,int e){
    adjvexNum=n;
    arcNum=e;
    int v1,v2;
    for(int i=0;i<adjvexNum;i++)
    for(int j=0;j<adjvexNum;j++)
    adj[i][j]=0;
    for(int i=0;i<adjvexNum;i++)
    visited[i]=0;
    for(int i=0;i<arcNum;i++){
        cin>>v1>>v2;
        adj[v1][v2]=1;
        adj[v2][v1]=1;
    }
}
void DFS(int i,MGraph &G,stack<int> s){
    s.push(i);
    cout<<s.top()<<"  ";
    G.visited[i]=1;
    for(int j=0;j<G.adjvexNum;j++){
    if(G.adj[i][j]==1&&G.visited[j]==0)
    DFS(j,G,s);
    }
}
int main(){
   int adjvexNum,arcNum;
   stack<int> s;
   cout<<"輸入頂點數和邊數:"<<endl; 
   cin>>adjvexNum>>arcNum;
   cout<<"輸入邊的資訊:"<<endl;
   MGraph G(adjvexNum,arcNum);
   cout<<"深度優先的遍歷結果為:"<<endl; 
   DFS(0,G,s);
   return 0;
}

這裡寫圖片描述

也許你會好奇,為什麼遍歷的結果和書裡面的不一樣啊!因為圖的深度優先遍歷不唯一啊,主要看你從0頂點的哪個鄰接點先開始遍歷,書本的是先遍歷4,而我的程式碼先遍歷小的,也就是1。

總的來說,肯定是遞迴的演算法程式設計的比較快些,哈哈!

程式碼如有錯誤,歡迎大家指出!