DFS、BFS空間時間復雜度分析


對於一個含有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)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM