廣度(寬度)優先搜索:隊列

上一章詳細的寫出了深度優先遍歷的四種情況的程序:
http://blog.csdn.net/zscfa/article/details/75947816

這一次來詳細說說廣度優先遍歷:
廣度優先搜索類似於二叉樹的層序遍歷,它的基本思想就是:首先訪問起始頂點v,接着由v出發,依次訪問v的各個未訪問過的鄰接頂點w1,w2,…,wi,然後再依次訪問w1,w2,…,wi的所有未被訪問過的鄰接頂點;再從這些訪問過的頂點出發,再訪問它們所有未被訪問過的鄰接頂點……依次類推,直到圖中所有頂點都被訪問過爲止。
這裏寫圖片描述
二、BFS算法的實現

與樹相比,圖的不同之處在於它存在迴路/環,因此在遍歷時一個頂點可能被訪問多次。爲了防止這種情況出現,我們使用一個訪問標記數組visited[]來標記頂點是否已經被訪問過。
在廣度優先搜索一個圖之前,我們首先要構造一個圖,圖的存儲方式主要有兩種:鄰接矩陣、鄰接表。

與上次一樣,我們來分類說明

(一)、隊列的方式實現
1、鄰接矩陣

#include<iostream>
#include<stdlib.h>
#include<queue>

#define MAX 100

using namespace std;

int visited[MAX];//用來記錄頂點是否被標誌

typedef struct
{
    char ves[MAX];//圖的頂點信息
    int vester;//頂點的數目
    int edge;//邊的數目
    int e[MAX][MAX];//圖的邊的信息

}MGraph;

void creatMGraph(MGraph *G)
{
    cout<<"please input the ves and edge:"<<endl;
    cin>>G->vester>>G->edge;

    int i;
    int j;
    int start;
    int end;
//初始化
    for(i = 0; i < G->vester; i++)
    {
        for(j = 0; j < G->vester; j++)
    {
        G->e[i][j] = 0;
    }
        visited[i] = 0;
    }

    cout<<"please input the edge,(vi,vj)"<<endl;
    for(i = 0; i < G->edge; i++)
    {
        cin>>start>>end;
    G->e[start][end] = 1;//構建無向圖
    G->e[start][end] = 1;
    }
}
/*主要思想:被訪問過的點壓入隊列,*/

void BFS(MGraph* G,int i)
{
    int k;
    int j;

    queue<int> q;

    visited[i] = 1;//標誌頂點i已經被訪問了
    cout<<i;

    q.push(i);

    while(!q.empty())
    {
        k = q.front();
    q.pop();

    for(j = 1; j < G->vester; j++)
    {
        if(G->e[k][j] != 0 && visited[j] != 1)
        {
    cout<<"k = "<<k<<endl;
            cout<<j<<endl;;
        visited[j] = 1;
        q.push(j);
        }
    }
    }
}

int main()
{
//    MGraph G = (MGraph*)malloc(MGraph);
    MGraph G;
    creatMGraph(&G);

    BFS(&G,0);

    return 0;
}

結果:
這裏寫圖片描述

2、鄰接表


#include<iostream>
#include<stdlib.h>
#include<queue>

#define MAX 100

using namespace std;

int visited[MAX] = {0};

struct Node// 邊表結點
{
    int adjves;//存儲頂點的下標
    struct Node* next;//連接下一個鄰點
};

typedef struct Node EdgeNode;

typedef struct VertexNode//頂點表結點
{
    int ves;//頂點的值
    EdgeNode* firstedge;//相連的頂點的值
}VertexNode,AdjList[MAX];

typedef struct
{
    AdjList adjlist;//鄰接表
    int ves;//頂點
    int edge;//邊
}MGraph;

void createMGraph(MGraph *G)
{
    int i;
    int start;
    int end;

    EdgeNode *e;

    cout<<"please input the ves and edge:"<<endl;
    cin>>G->ves>>G->edge;
//初始化
    cout<<"please input the ves:"<<endl;

    for(i = 0; i < G->ves; i++)//輸入頂點
    {
        cin>>G->adjlist[i].ves;
    G->adjlist[i].firstedge = NULL;
    }
//創建鄰接矩陣

    cout<<"please input the edges:"<<endl;;
    for(i = 0; i < G->edge; i++)
    {
        cin>>start>>end;

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間
    e->adjves = end;
    e->next = G->adjlist[start].firstedge;
    G->adjlist[start].firstedge = e;//類似於鏈表的前插

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間
    e->adjves = start;
    e->next = G->adjlist[end].firstedge;
    G->adjlist[end].firstedge = e;//類似於鏈表的前插
    }
}
void bfs(MGraph *G)
{
    int i;
    int k;

    EdgeNode* p;

    queue<int> q;

    for(i = 0; i < G->ves; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < G->ves; i++)
    {
        if(visited[i] == 0)
    {
        visited[i] = 1;
        cout<<G->adjlist[i].ves;
        q.push(i);

        while(!q.empty())
        {
        k = q.front();
        q.pop();

        p = G->adjlist[k].firstedge;

        while(p)
        {
            if(visited[i] == 0)
            {
                visited[i] = 1;

                cout<<G->adjlist[p->adjves].ves;
            q.push(p->adjves);
            }
            p = p->next;
        }

        }
    }
    }
}
int main()
{
    MGraph G;
    createMGraph(&G);

    bfs(&G);
    return 0;
}

結果:
這裏寫圖片描述

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