採用鄰接矩陣存儲圖的廣度優先遍歷算法的實現

廣度優先

廣度優先搜索遍歷連通圖ios

#include <iostream>
using namespace std;

#define MVNum 100                           //最大頂點數
#define MAXQSIZE 100                        //最大隊列長度
                        
typedef char VerTexType;                    //假設頂點的數據類型爲字符型
typedef int ArcType;                        //假設邊的權值類型爲整型
bool visited[MVNum];                        //訪問標誌數組,其初值爲"false" 

//-----圖的鄰接矩陣存儲表示----- 
typedef struct{ 
    VerTexType vexs[MVNum];                 //頂點表
    ArcType arcs[MVNum][MVNum];             //鄰接矩陣
    int vexnum,arcnum;                      //圖的當前點數和邊數
}Graph;

//----隊列的定義及操做--------
typedef struct{
    ArcType *base;                          //初始化的動態分配存儲空間
    int front;                              //頭指針,若隊列不空,指向隊頭元素
    int rear;                               //尾指針,若隊列不空,指向隊尾元素的下一個位置
}sqQueue;

void InitQueue(sqQueue &Q){
    //構造一個空隊列Q
    Q.base = new ArcType[MAXQSIZE];
    if(!Q.base)     exit(1);                //存儲分配失敗
    Q.front = Q.rear = 0;
}//InitQueue

void EnQueue(sqQueue &Q, ArcType e){
    //插入元素e爲Q的新的隊尾元素
    if((Q.rear + 1) % MAXQSIZE == Q.front)
        return;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXQSIZE;
}//EnQueue

bool QueueEmpty(sqQueue Q){
    //判斷是否爲空隊
    if(Q.rear == Q.front)
        return true;
    return false;
}//QueueEmpty

void DeQueue(sqQueue &Q, ArcType &u){
    //隊頭元素出隊並置爲u 
    u = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;
}//DeQueue                                  
//--------------------------------------------------

int LocateVex(Graph G , VerTexType v){
    //肯定點v在G中的位置
    for(int i = 0; i < G.vexnum; ++i)
        if(G.vexs[i] == v)
            return i;
        return -1;
}//LocateVex



void CreateUDN(Graph &G){ 
    //採用鄰接矩陣表示法,建立無向網G 
    int i , j , k;
    cout <<"請輸入總頂點數,總邊數,以空格隔開:";
    cin >> G.vexnum >> G.arcnum;                            //輸入總頂點數,總邊數
    cout << endl;
    cout << "輸入點的名稱,如a" << endl;
    for(i = 0; i < G.vexnum; ++i){   
        cout << "請輸入第" << (i+1) << "個點的名稱:";
        cin >> G.vexs[i];                                   //依次輸入點的信息 
    }
    cout << endl;
    for(i = 0; i < G.vexnum; ++i)                           //初始化鄰接矩陣,邊的權值均置爲極大值MaxInt 
        for(j = 0; j < G.vexnum; ++j)   
            G.arcs[i][j] = 0; 
    cout << "輸入邊依附的頂點,如a b" << endl;
    for(k = 0; k < G.arcnum;++k){                           //構造鄰接矩陣 
        VerTexType v1 , v2;
        cout << "請輸入第" << (k + 1) << "條邊依附的頂點:";
        cin >> v1 >> v2;                                    //輸入一條邊依附的頂點
        i = LocateVex(G, v1);  j = LocateVex(G, v2);        //肯定v1和v2在G中的位置,即頂點數組的下標 
        G.arcs[i][j] = 1;                                   //邊<v1, v2>的權值置爲w 
        G.arcs[j][i] = G.arcs[i][j];                        //置<v1, v2>的對稱邊<v2, v1>的權值爲w 
    }//for 
}//CreateUDN

int FirstAdjVex(Graph G , int v){
    //返回v的第一個鄰接點
    int i;
    for(i = 0 ; i < G.vexnum ; ++i){
        if(G.arcs[v][i] == 1 && visited[i] == false)
            return i;
    }
    return -1;
}//FirstAdjVex

int NextAdjVex(Graph G , int u , int w){
    //返回v相對於w的下一個鄰接點
    int i;
    for(i = w ; i < G.vexnum ; ++i){
        if(G.arcs[u][i] == 1 && visited[i] == false)
            return i;
    }
    return -1;
}//NextAdjVex

void BFS (Graph G, int v){ 
    //按廣度優先非遞歸遍歷連通圖G 
    sqQueue Q;
    ArcType u;
    ArcType w;
    // int u,w;
     cout << G.vexs[v] << "  ";    visited[v] = true;                           //訪問第v個頂點,並置訪問標誌數組相應份量值爲true 
    InitQueue(Q);                                                               //輔助隊列Q初始化,置空         
    EnQueue(Q, v);                                                              //v進隊 
    while(!QueueEmpty(Q)){                                                      //隊列非空 
        DeQueue(Q, u);                                                      //隊頭元素出隊並置爲u
        for(w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)){
            //依次檢查u的全部鄰接點w  ,修改該語句使得可以獲得正確
             
            if(!visited[w]){                                                    //w爲u的還沒有訪問的鄰接頂點 
                cout << G.vexs[w] << "  ";   visited[w] = true;                 //訪問w,並置訪問標誌數組相應份量值爲true 
                EnQueue(Q, w);                                                  //w進隊 
            }//if 
        }//for
    }//while 
}//BFS

int main(){
    cout << "************算法6.7 廣度優先搜索遍歷連通圖**************" << endl << endl;
    Graph G;
    CreateUDN(G);
    cout << endl;
    cout << "無向連通圖G建立完成!" << endl << endl;
    
    cout << "請輸入遍歷連通圖的起始點:";
    VerTexType c;
    cin >> c;
    
    int i;
    for(i = 0 ; i < G.vexnum ; ++i){
        if(c == G.vexs[i])
            break;
    }
    cout << endl;
    while(i >= G.vexnum){
        cout << "該點不存在,請從新輸入!" << endl;
        cout << "請輸入遍歷連通圖的起始點:";
        cin >> c;
        for(i = 0 ; i < G.vexnum ; ++i){
            if(c == G.vexs[i])
                break;
        }
    }
    cout << "廣度優先搜索遍歷連通圖結果:" << endl;
    BFS(G , i);
    
    cout <<endl;
    return 0;
}//main
相關文章
相關標籤/搜索