【圖(上)】圖的遍歷,深度優先,廣度優先
阿新 • • 發佈:2018-11-22
深度優先搜尋(Depth First Search, DFS)
類似於樹的先序遍歷
先將根節點設定成已經訪問過,對根節點的每一個鄰接點,選取一個,檢視有沒有訪問過,沒有訪問,設定成訪問,並將此節點作為根結點,重複上述步驟;如果所有鄰接點都已經訪問過,放回到上一步的根節點中,檢視是否有沒有訪問的鄰接點,直到返回到第一步的根節點中。
void DFS(Vertex V)
{
visited[V] = true;
for (V 的每個鄰接點W)
if (!visited[W])
DFS(W);
}
若有N個頂點、E條邊,時間複雜度是:
- 用鄰接表儲存圖,有O(N+E)
- 用鄰接矩陣儲存圖,有O(N2)
廣度優先搜尋(Breadth First Search, BFS)
類似於樹的層序遍歷,先將一個元素壓入佇列之中,設定該元素為已訪問,每次從佇列取出一個元素,並將該元素所有未訪問的鄰接點元素壓入佇列中,直到佇列為空,每次壓入佇列,將該元素設定為已經訪問。
void BFS(Vertex V)
{
visited[V] = true;
Enqueue(V, Q);
while (!IsEmpty(Q))
{
V = Dequeue(Q);
for (V 的每個鄰接點W)
if (!visited[W])
{
visited[ W] = true;
Enqueue(W, Q);
}
}
}
若有N個頂點、E條邊,時間複雜度是:
- 用鄰接表儲存圖,有O(N+E)
- 用鄰接矩陣儲存圖,有O(N2)
為什麼需要兩種遍歷?
小人從開始的地方找到綠色的出口,白色可以通過,黑色堵住了,可以對角線走,圖中小人出現的地方為訪問過的結點,可以看到不同的搜尋訪問的複雜度時不一樣的。
圖不連通怎麼辦?
-
連通
:如果從V到W存在一條(無向)路徑,則稱V和W是連通的 -
路徑
:V到W的路徑是一系列頂點{V, v1, v2, …,vn, W}的集合,其中任一對相鄰的頂點間都有圖中的邊。路徑的長度
簡單路徑
-
迴路
:起點等於終點的路徑 -
連通圖
:圖中任意兩頂點均連通 -
連通分量
:無向圖的極大連通子圖- 極大頂點數:再加1個頂點就不連通了
- 極大邊數:包含子圖中所有頂點相連的所有邊
-
強連通
:有向圖中頂點V和W之間存在雙向路徑,則稱V和W是強連通的 -
強連通圖
:有向圖中任意兩頂點均強連通 -
強連通分量
:有向圖的極大強連通子圖
void DFS(Vertex V)
{
visited[V] = true;
for (V 的每個鄰接點W)
if (!visited[W])
DFS(W);
}
void ListComponents(Graph G)
{
for (each V in G)
if (!visited[V])
DFS(V); /*or BFS( V )*/
}