圖的資料結構不像二叉樹那樣,有明顯的父子節點和兄弟節點的關係,它只有一個關係就是鄰接關係。故對圖中頂點的訪問要採用標誌數組(來確定改結點是否被訪問,去除重複訪問)。並且對圖的深度遍曆採用遞迴的方式是較高效的。
1.深度遍曆(DFS)
#include<iostream>#include<stdlib.h>using namespace std;//DFS#define MAX 10bool visited[MAX];status (*VisitFunc)(int v);//定義函數指標 void DFS(Graph G,int v){ visited[v]=TRUE;VisitFunc(v); for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!visited[w]) DFS(G,w);//與樹的DFS的區別 }void DFSt(Graph G,status(*Visit)(int v)){ VisitFunc = Visit;//為函數指標賦值 for(v=0;v<G.vexnum;++v) visited[v]=FALSE;//初始化標誌數組 //memset(visited,0,sizeof(visited)); for(v=0;v<G.vexnum;++v) if(!visited[v])DFS(G,v); }
2.廣度遍曆(BFS)
廣度優先遍曆利用輔助隊列後,很好的達到了遍曆的效果。
#include<iostream>#include<stdlib.h>using namespace std;//BFS#define MAX 10bool visited[MAX];status (*VisitFunc)(int v);//定義函數指標 void BSF(Graph G,Status(* Visit)(int v)){ for(v=0;v<G.vexnum;++v) visited[v]=FALSE; InitQueue(Q); for(v=0;v<G.vexnum;++v) { if(!visited[v]) { visited[v]=TRUE;Visit(v); EnQueue(Q,v); while(!QueueEmpty(Q)) { DeQueue(Q,u); for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w)) { if(!Visited[w]) { Visited[w]=TRUE;Visit(w); EnQueue(Q,w);//把節點的所有鄰接節點都入隊,並且都遍曆一次 } } } } } }
3.總結
對於圖結構,若採用鄰接表格儲存體的話,FirstAdjVex和NextAdjVex是很好得到的