1. 程式人生 > >資料結構——圖的深度/廣度優先遍歷

資料結構——圖的深度/廣度優先遍歷

這是上一篇:圖的儲存方式——鄰接矩陣

從整體來看,我個人認為深度優先有點類似二叉樹先序遍歷,都是將訪問節點壓入到棧,然後看是否有延伸節點,若沒有則出棧,返回到上一節點;而廣度優先則與二叉樹層次遍歷比較像,離出發節點比較近的點先被訪問。因此本篇我採用非遞迴的方式進行圖的遍歷,分別採用的是站和佇列的資料結構

#include<iostream>
#include<limits.h>
#include<stack>
#include<queue>

using namespace std;

#define MAXVEX 100

typedef struct
{
    int matrix[MAXVEX][MAXVEX];
    int numNodes, numEdges;
} Graph;

void CreateGraph(Graph *Gp)
{
    int i, j, k, w;
    bool isDirected;
    cout<<"無向圖請輸入0,有向圖請輸入1"<<endl;
    cin>>isDirected;
    cout<<"請輸入頂點數和邊數(空格分隔):"<<endl;
    cin>>Gp->numNodes>>Gp->numEdges;;
    for (i=1;i<=Gp->numNodes;i++)
    {
        for (j=1;j<=Gp->numNodes;j++)
        {
            if (i==j)
                Gp->matrix[i][j]=0;
            else
                Gp->matrix[i][j]=INT_MAX;
        }
    }
    cout<<"請輸入邊(vi, vj)和權值w,三個變數空格分隔即可:"<<endl;
    for (k=0;k<Gp->numEdges;k++)
    {
        cin>>i>>j>>w;
        Gp->matrix[i][j]=w;
        if(!isDirected)
            Gp->matrix[j][i]=Gp->matrix[i][j];
    }
}

void ShowGraph(Graph M){
    int i, j;
    for(i=1;i<=M.numNodes;i++){
        for(j=1;j<=M.numNodes;j++){
            if(M.matrix[i][j]!=INT_MAX)
                cout<<M.matrix[i][j]<<" ";
        else
            cout<<"*"<<" ";
        }
        cout<<endl;
    }
}

void Graph_Dfs(Graph M, int visiting_Node){
    bool *isVisited=new bool[M.numNodes];
    for(int i=1;i<M.numNodes;i++)
        isVisited[i]=false;
    int visited_count=0;//記錄已經訪問過的節點
    stack<int> p;
    while(visited_count<M.numNodes){
        if(isVisited[visiting_Node]==false){
            cout<<visiting_Node<<" ";
            visited_count++;
        }
        p.push(visiting_Node);
        isVisited[visiting_Node]=true;
        int j;
        for(j=1;j<=M.numNodes;j++){
            if(M.matrix[visiting_Node][j]!=0 && M.matrix[visiting_Node][j]!=INT_MAX && isVisited[j]==false )
                break;
        }
        if(j==M.numNodes+1){
            p.pop();
            if(!p.empty()){
                visiting_Node=p.top();
                p.pop();
            }
            else
                break;
        }
        else
            visiting_Node=j;
    }
}

void Graph_Bfs(Graph M, int visiting_Node){
    bool *isVisited=new bool[M.numNodes];
    for(int i=1;i<M.numNodes;i++)
        isVisited[i]=false;
    int visited_count=0;//記錄已經訪問過的節點
    queue<int> p;
    while(visited_count<M.numNodes){
        if(isVisited[visiting_Node]==false){
            cout<<visiting_Node<<" ";
            visited_count++;
        }
        isVisited[visiting_Node]=true;
        p.push(visiting_Node);
        for(int j=1;j<=M.numNodes;j++){
            if(M.matrix[visiting_Node][j]!=0 && M.matrix[visiting_Node][j]!=INT_MAX && isVisited[j]==false){
                p.push(j);
            }
        }
        p.pop();
        visiting_Node=p.front();
    }
}

int main(void)
{
    Graph M;
    CreateGraph(&M);
    cout<<"鄰接矩陣為:"<<endl;
    ShowGraph(M);

    cout<<"該圖的深度遍歷為:"<<endl;
    Graph_Dfs(M,1);

    cout<<endl;

    cout<<"該圖的廣度遍歷為:"<<endl;
    Graph_Bfs(M,1);

    return 0;
}

執行結果: