對於一個含有n個節點、e條邊的連通無向圖,兩種遍歷方式,分別分析時間空間復雜度。
深度遍歷:DFS
它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。
若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
偽代碼描述:
1 void DFSTraverseAL(ALGraph *G) 2 { /*深度優先遍歷以鄰接表存儲的圖G*/ 3 int i; 4 for (i = 0; i < G->n; i++) 5 visited[i] = FALSE; /*標志向量初始化*/ 6 for (i = 0; i < G->n; i++) 7 if (!visited[i]) 8 DFSAL(G, i); /*vi 未訪問過,從vi 開始DFS 搜索*/ 9 } /*DFSTraveseAL*/ 10 11 void DFSAL(ALGraph *G, int i) 12 { /*以Vi 為出發點對鄰接表存儲的圖G 進行DFS 搜索*/ 13 EdgeNode *p; 14 printf("visit vertex:V%c\n", G->adjlist[i].vertex); /*訪問頂點Vi*/ 15 visited[i] = TRUE; /*標記Vi 已訪問*/ 16 p = G->adjlist[i].firstedge; /*取Vi 邊表的頭指針*/ 17 while (p) /*依次搜索Vi 的鄰接點Vj,j=p->adjva*/ 18 { 19 if (!visited[p->adjvex]) /*若Vj 尚未訪問,則以Vj 為出發點向縱深搜索*/ 20 DFSAL(G, p->adjvex); 21 p = p->next; /*找Vi 的下一個鄰接點*/ 22 } 23 } /*DFSAL*/
1)DFS、采用鄰接矩陣表示
空間復雜度:
由於DFS需要一個遞歸工作棧,最差的情況是如圖所示。當從第一個節點開始遍歷時,先訪問它,修改它的訪問標記。然后找到它的第一個鄰居(把它的鄰居稱為a),訪問a,修改a的訪問標記。
從a找到a的鄰居(稱為b),訪問b,修改b的訪問標記 ,...,依次遞歸,每個節點都需要進入函數調用棧,最深的函數棧層數為n,故其空間復雜度為O(n-1)~O(n)。
時間復雜度:
時間復雜度為非兩個部分:a:訪問每個節點花費的時間 b:在每個節點找鄰居花費的時間。
a:n個節點需要O(n);
b:由於是鄰接矩陣,對於節點i,需要掃描第i行的每一個元素,需要O(n);
總的復雜度O(n^2)。
2)DFS、采用鄰接表表示
空間復雜度:
同鄰接矩陣的分析
時間復雜度:
時間復雜度分為兩個部分:a:訪問每個節點花費的時間 b:在每個節點找鄰居花費的時間。
a:n個節點需要O(n);
b:采用鄰接表,總共的找鄰居時間復雜度就是遍歷邊表的時間復雜度。對於有向圖:O(e),對於無向圖O(2e)~O(e)(取最高階);
總的復雜度O(n+e)。
廣度遍歷:BFS
偽代碼描述:
1 void BFSTraverse(Graph G, Status (*Visit)(int v)) 2 { /*按廣度優先非遞歸遍歷圖G。使用輔助隊列Q 和訪問標志數組visited*/ 3 for (v = 0; v < G, vexnum; ++v) 4 visited[v] = FALSE 5 InitQueue(Q); /*置空的隊列Q*/ 6 if (!visited[v]) /*v 尚未訪問*/ 7 { 8 EnQucue(Q, v); /*v 入隊列*/ 9 while (!QueueEmpty(Q)) 10 { 11 DeQueue(Q, u); /*隊頭元素出隊並置為u*/ 12 visited[u] = TRUE; 13 visit(u); /*訪問u*/ 14 for (w = FistAdjVex(G, u); w; w = NextAdjVex(G, u, w)) 15 if (!visited[w]) 16 EnQueue(Q, w); /*u 的尚未訪問的鄰接頂點w 入隊列Q*/ 17 } 18 } 19 } /*BFSTraverse*/
它的思想是:從圖中某頂點v出發,在訪問了v之后依次訪問v的各個未曾訪問過的鄰接點,然后分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於后被訪問的頂點的鄰接點被訪問。
直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作為新的起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
1)BFS、采用鄰接矩陣表示
空間復雜度:
無論是鄰接表還是鄰接矩陣,BFS算法需要借助一個輔助隊列,在最壞的情況下(如下圖從中心節點出發),n個頂點需全入隊一次,空間復雜度O(n);
時間復雜度:
時間復雜度為非兩個部分:a:訪問每個節點花費的時間 b:在每個節點找鄰居花費的時間。
a:n個節點需要O(n);
b:由於是鄰接矩陣,對於節點i,需要掃描第i行的每一個元素,需要O(n);
總的復雜度O(n^2)。
2)BFS、采用鄰接表表示
空間復雜度:
同上
時間復雜度:
時間復雜度分為兩個部分:a:訪問每個節點花費的時間 b:在每個節點找鄰居花費的時間。
a:n個節點需要O(n);
b:采用鄰接表,總共的找鄰居時間復雜度就是遍歷邊表的時間復雜度。對於有向圖:O(e),對於無向圖O(2e)~O(e)(取最高階);
總的復雜度O(n+e)。