圖的遍曆和樹的遍曆類似,我們希望從圖中某一頂點出發訪遍圖中其餘頂點,且使每一個頂點僅被訪問一次,這一過程 就叫做圖的遍曆(Traverse Graph)。
圖的遍曆方法一般有兩種,第一種是我們在前面講過的《深度優先遍曆 (Depth First Search)》,也有稱為深度優先搜尋,簡稱為DFS。第二種是廣度優先遍曆(Breadth First Search), 也有稱為廣度優先搜尋,簡稱為BFS。我們在《隊列與廣度優先搜尋》中已經較為詳細地講述了廣度優先搜尋的策略,這裡 不再贅述。如果說圖的深度優先遍曆類似樹的前序走訪,那麼圖的廣度優先遍曆就類似於樹的層序遍曆了,我們把圖7-5-3 的第一幅圖稍微變形成第二幅圖所示,這樣層次感就更強了,廣度優先遍曆需要用到隊列的操作,可以參考《隊列的順序存 儲結構》。
下面只給出鄰接矩陣和鄰接表格儲存體方式時的圖的廣度優先遍曆的演算法代碼,沒有給出整體可供測試回合的代碼,其實只 需要再寫一個建立圖的函數就可以進行整體測試了,可以參考《鄰接矩陣建立圖》和《鄰接表建立圖》
一、如果我 們使用的是鄰接矩陣的方式,則代碼如下:
typedef char VertexType; /* 頂點類型應由使用者定義 */typedef int EdgeType; /* 邊上的權實值型別應由使用者定義 */ #define MAXSIZE 9 /* 儲存空間初始分配量 */#define MAXEDGE 15#define MAXVEX 9 typedef struct{ VertexType vexs[MAXVEX]; /* 頂點表 */ EdgeType arc[MAXVEX][MAXVEX];/* 鄰接矩陣,可看作邊表 */ int numVertexes, numEdges; /* 圖中當前的頂點數和邊數 */} MGraph; /* 鄰接矩陣的廣度遍曆演算法 */void BFSTraverse(MGraph G){ int i, j; Queue Q; for (i = 0; i < G.numVertexes; i++) visited[i] = false; InitQueue(&Q);/* 初始化一輔助用的隊列 */ for (i = 0; i < G.numVertexes; i++)/* 對每一個頂點做迴圈 */ { if (!visited[i])/* 若是未訪問過就處理 */ { visited[i] = true;/* 設定當前頂點訪問過 */ cout << G.vexs[i] << ' '; /* 列印頂點,也可以其它操作 */ EnQueue(&Q, i);/* 將此頂點入隊列 */ while (!QueueEmpty(Q))/* 若當前隊列不為空白 */ { DeQueue(&Q, &i);/* 將隊對元素出隊列,賦值給i */ for (j = 0 ; j < G.numVertexes; j++) { /* 判斷其它頂點若與當前頂點存在邊且未訪問過 */ if (G.arc[i][j] == 1 && !visited[j]) { visited[j] = true;/* 將找到的此頂點標記為已訪問 */ cout << G.vexs[j] << ' '; /* 列印頂點 */ EnQueue(&Q, j);/* 將找到的此頂點入隊列 */ } } } } }}
遍曆結果為:A B F C G I E D H (上圖所示的圖結構)