1. 程式人生 > >圖的遍歷之深度優先搜尋演算法&&廣度優先優先演算法的實現

圖的遍歷之深度優先搜尋演算法&&廣度優先優先演算法的實現

一.序
和樹的遍歷類似,我們希望從圖中的某一個頂點出發訪問圖中其餘頂點,保證每個頂點只被訪問一次,這一過程叫做圖的遍歷。圖的遍歷演算法是求解圖的連通性問題(最小生成樹),拓撲排序,求關鍵路徑的基礎。
而為了保證同一個頂點不被訪問多次,在遍歷圖的的過程中,必須記下訪問過的頂點。為此,需要設立一個輔助陣列visited[0..n-1],初始值設定為0或假,這樣其不為0或者為真時,表示此頂點已經被訪問過。
通常有兩條遍歷圖的路徑:深度優先搜尋和廣度優先搜尋。他們對有向圖和無向圖都適用。
二.簡單介紹兩種演算法

深度優先搜尋演算法類似於二叉樹的先根遍歷,廣度優先搜尋演算法類似於二叉樹的層次遍歷

如下圖,分別以v1頂點(當然可以是其他頂點)為起始對其進行深度優先搜尋和廣度優先搜尋
這裡寫圖片描述

深度優先搜尋

這裡寫圖片描述

那麼,結果為v1–>v2–>v4–>v8–>v5–>v3–>v6–>v7

廣度優先搜尋

這裡寫圖片描述

那麼,結果為v1–>v2–>v3–>v4–>v5–>v6–>v7–>v8

三.演算法實現
這裡寫圖片描述
這裡,我們採用鄰接表的方式建立圖,當然,讀者可以選擇鄰接矩陣的方式,這並不影響我們的演算法實現。
1.深度優先搜尋演算法
實現思路:
(1)首先需要建立一個訪問標記visited陣列用來儲存各頂點是否被訪問過,初始化為false,表示未被訪問。
(2)以v為起始頂點

,遞迴遍歷圖中各頂點,若訪問標記符為false,則列印該頂點,將該頂點的訪問標記符置為true,繼續訪問該頂點的第一個鄰接頂點,若其訪問標記符為false,則列印該頂點,將該頂點的訪問標記符置為true;若其訪問標記符為true,則該頂點已經被訪問,訪問其下一個鄰接頂點。就這樣,以此類推。直至頂點訪問結束!

template <class Type>
void GraphLink<Type>::DFS(const Type &vertex)
{
    bool *visted = new bool[numVertices];
    try
    {
        if
(NULL == visted) throw visted; } catch(...) { ERROR error; error.ERROR_WAHT(); } for(int i=0; i<numVertices; ++i) visted[i] = false; DFS(vertex, visted); cout<<"over."<<endl; delete []visted; } template <class Type> void GraphLink<Type>::DFS(const Type &v, bool visted[]) { cout<<v<<"-->"; visted[GetPosVertex(v)] = true; int w = GetFirstNeighbor(v); while(w != -1) { Type w_vertex = GetValueByPos(w); if(!visted[w]) DFS(w_vertex, visted); w = GetNextNeighbor(v, w_vertex); } }