圖的遍歷- 圖內多環 多連通圖問題

http://www.cnblogs.com/dolphin0520/archive/2011/07/13/2105236.html

遞歸 非遞歸(用棧)

圖的遍歷有兩種遍歷方式:深度優先遍歷(depth-first search)和廣度優先遍歷(breadth-first search)。

1.深度優先遍歷

   基本思想:首先從圖中某個頂點v0出發,訪問此頂點,然後依次從v0相鄰的頂點出發深度優先遍歷,直至圖中所有與v0路徑相通的頂點都被訪問了;若此時尚有頂點未被訪問,則從中選一個頂點作爲起始點,重複上述過程,直到所有的頂點都被訪問。可以看出深度優先遍歷是一個遞歸的過程。

   如下圖中的一個無向圖

   

  其深度優先遍歷得到的序列爲:

  0->1->3->7->4->2->5->6

2.廣度優先遍歷

   基本思想:首先,從圖的某個頂點v0出發,訪問了v0之後,依次訪問與v0相鄰的未被訪問的頂點,然後分別從這些頂點出發,廣度優先遍歷,直至所有的頂點都被訪問完。

   如上面圖中

   其廣度優先遍歷得到的序列爲:

   0->1->2->3->4->5->6->7

#include<iostream>
#include<queue>
#include<stack>
#include<stdlib.h>
#define MAX 100
using namespace std;
 
typedef struct
{
    int edges[MAX][MAX];    //鄰接矩陣
    int n;                  //頂點數
    int e;                  //邊數
}MGraph;
 
bool visited[MAX];          //標記頂點是否被訪問過
 
void creatMGraph(MGraph &G)    //用引用作參數
{
    int i,j;
    int s,t;                 //存儲頂點編號
    int v;                   //存儲邊的權值
    for(i=0;i<G.n;i++)       //初始化
    {
        for(j=0;j<G.n;j++)
        {
            G.edges[i][j]=0;
        }
        visited[i]=false;
    }
    for(i=0;i<G.e;i++)      //對矩陣相鄰的邊賦權值
    {
        scanf("%d %d %d",&s,&t,&v);   //輸入邊的頂點編號以及權值
        G.edges[s][t]=v;
    }
}
 
void DFS(MGraph G,int v)      //深度優先搜索
{
    int i;
    printf("%d ",v);          //訪問結點v
    visited[v]=true;
    for(i=0;i<G.n;i++)       //訪問與v相鄰的未被訪問過的結點
    {
        if(G.edges[v][i]!=0&&visited[i]==false)
        {
            DFS(G,i);
        }
    }
}
 
void DFS1(MGraph G,int v)   //非遞歸實現
{
    stack<int> s;
    printf("%d ",v);        //訪問初始結點
    visited[v]=true;
    s.push(v);              //入棧
    while(!s.empty())
    {
        int i,j;
        i=s.top();          //取棧頂頂點
        for(j=0;j<G.n;j++)  //訪問與頂點i相鄰的頂點
        {
            if(G.edges[i][j]!=0&&visited[j]==false)
            {
                printf("%d ",j);     //訪問
                visited[j]=true;
                s.push(j);           //訪問完後入棧
                break;               //找到一個相鄰未訪問的頂點,訪問之後則跳出循環
            }
        }
        if(j==G.n)                   //如果與i相鄰的頂點都被訪問過,則將頂點i出棧
            s.pop();
    }
}
 
void BFS(MGraph G,int v)      //廣度優先搜索
{
    queue<int> Q;             //STL模板中的queue
    printf("%d ",v);
    visited[v]=true;
    Q.push(v);
    while(!Q.empty()) 
    {
        int i,j;
        i=Q.front();         //取隊首頂點
        Q.pop();
        for(j=0;j<G.n;j++)   //廣度遍歷
        {
            if(G.edges[i][j]!=0&&visited[j]==false)
            {
                printf("%d ",j);
                visited[j]=true;
                Q.push(j);
            }
        }
    }
}
 
int main(void)
{
    int n,e;    //建立的圖的頂點數和邊數
    while(scanf("%d %d",&n,&e)==2&&n>0)
    {
        MGraph G;
        G.n=n;
        G.e=e;
        creatMGraph(G);
        DFS(G,0);
        printf("\n");
    //  DFS1(G,0);
    //  printf("\n");
    //  BFS(G,0);
    //  printf("\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章