1. 程式人生 > >資料結構篇:圖的遍歷(二:廣度優先遍歷)

資料結構篇:圖的遍歷(二:廣度優先遍歷)

廣度優先遍歷,又稱廣度優先搜尋,縮寫BFS

如果說深度優先遍歷是相當於樹的前序遍歷,那麼,廣度優先遍歷就相當於樹的層序遍歷。

以上面那張圖為例就是,ABFCIGEDH

程式碼實現

void AdjacencyList::BFSTraverse(GraphAdjList *G) {

    EdgeNode *p;
    queue<int> Q;
    for (int i = 0; i < G->numVertexes; i++)
    {
        visted[i] = 0;
    }
    cout << "廣度優先遍歷結果為:";
    for (int i = 0; i < G->numVertexes; i++)
    {
        if (visted[i] == 0)
        {
            visted[i] = 1;
            cout << G->adjList[i].data << "--";
            Q.push(i);
            while (!Q.empty())
            {
                Q.front()=i;
                Q.pop();
                p = G->adjList[i].firstedge;
                while (p)
                {
                    if (visted[p->adjvex] == 0)
                    {
                        visted[p->adjvex] = 1;
                        cout << G->adjList[p->adjvex].data << "--";
                        Q.push(p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }
}

完整程式碼

//
// Created by 煙雨迷離半世殤 on 2018/11/21.
//

#include <iostream>
#include <queue>

using namespace std;

//訪問標誌的陣列,為1表示訪問過,為0表示未被訪問
int visted[100];
//邊表結點
typedef struct EdgeNode {
    //頂點對應的下標
    int adjvex;
    //指向下一個鄰接點
    struct EdgeNode *next;
} edgeNode;

//頂點表結點
typedef struct VertexNode {
    //頂點資料
    char data;
    //邊表頭指標
    edgeNode *firstedge;
} VertexNode, AdjList[100];

//集合
typedef struct {
    AdjList adjList;
    //頂點數和邊數
    int numVertexes, numEdges;
} GraphAdjList;

class AdjacencyList {
public:

    void CreateALGraph(GraphAdjList *G);

    void ShowALGraph(GraphAdjList *G);

    void DFS(GraphAdjList *G, int i);

    //深度優先遍歷
    void DFSTraverse(GraphAdjList *G);

    //廣度優先遍歷
    void BFSTraverse(GraphAdjList *G);

    void Test();


};

void AdjacencyList::CreateALGraph(GraphAdjList *G) {
    int i, j, k;
    edgeNode *e;
    cout << "輸入頂點數和邊數" << endl;
    //輸入頂點數和邊數
    cin >> G->numVertexes >> G->numEdges;
    //讀入頂點資訊,建立頂點表
    for (i = 0; i < G->numVertexes; i++)
    {
        //輸入頂點資訊
        cin >> G->adjList[i].data;
        //將邊表置為空表
        G->adjList[i].firstedge = NULL;
    }
    //建立邊表(頭插法)
    for (k = 0; k < G->numEdges; k++)
    {
        cout << "輸入邊(vi,vj)上的頂點序號" << endl;
        cin >> i >> j;
        e = new EdgeNode;
        e->adjvex = j;
        e->next = G->adjList[i].firstedge;
        G->adjList[i].firstedge = e;

        e = new EdgeNode;

        e->adjvex = i;
        e->next = G->adjList[j].firstedge;
        G->adjList[j].firstedge = e;
    }
}

void AdjacencyList::Test() {
    cout << "ALL IS OK." << endl;
}

void AdjacencyList::ShowALGraph(GraphAdjList *G) {
    for (int i = 0; i < G->numVertexes; i++)
    {
        cout << "頂點" << i << ": " << G->adjList[i].data << "--firstedge--";
        edgeNode *p = new edgeNode;
        p = G->adjList[i].firstedge;
        while (p)
        {
            cout << p->adjvex << "--Next--";
            p = p->next;
        }
        cout << "--NULL" << endl;
    }

}

void AdjacencyList::DFS(GraphAdjList *G, int i) {
    EdgeNode *p;
    visted[i] = 1;
    cout << G->adjList[i].data << "--";
    p = G->adjList[i].firstedge;
    while (p)
    {
        if (!visted[p->adjvex])
        {
            //遞迴訪問
            DFS(G, p->adjvex);
        }
        p = p->next;
    }

}

void AdjacencyList::DFSTraverse(GraphAdjList *G) {
    //初始化所有頂點都沒有訪問過
    cout << "深度優先遍歷結果為:" << endl;
    for (int i = 0; i < G->numVertexes; i++)
    {
        visted[i] = 0;
    }
    for (int i = 0; i < G->numVertexes; i++)
    {
        if (visted[i] == 0)
        {
            DFS(G, i);
        }
    }
}

void AdjacencyList::BFSTraverse(GraphAdjList *G) {

    EdgeNode *p;
    queue<int> Q;
    for (int i = 0; i < G->numVertexes; i++)
    {
        visted[i] = 0;
    }
    cout << "廣度優先遍歷結果為:";
    for (int i = 0; i < G->numVertexes; i++)
    {
        if (visted[i] == 0)
        {
            visted[i] = 1;
            cout << G->adjList[i].data << "--";
            Q.push(i);
            while (!Q.empty())
            {
                Q.front()=i;
                Q.pop();
                p = G->adjList[i].firstedge;
                while (p)
                {
                    if (visted[p->adjvex] == 0)
                    {
                        visted[p->adjvex] = 1;
                        cout << G->adjList[p->adjvex].data << "--";
                        Q.push(p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }
}


int main() {

    AdjacencyList adjacencyList;
    GraphAdjList *GA = new GraphAdjList;
    adjacencyList.Test();
    adjacencyList.CreateALGraph(GA);
    adjacencyList.ShowALGraph(GA);
    adjacencyList.BFSTraverse(GA);
    return 0;
}


以下面這張圖為例

 

執行截圖