1. 程式人生 > >搜尋_DFS(深度優先搜尋)_演算法分析

搜尋_DFS(深度優先搜尋)_演算法分析

    為方便對DFS演算法的考察, 為圖G的每個結點設定屬性color表示結點的顏色, color可取WHITE(白色), GRAY(灰色)或BLACK(黑色), 同時為每個結點設定屬性d表示剛進行對此結點訪問的時刻, 設定屬性f表示剛結束對此結點訪問的時刻, 先給出如下DFS和DFS_visit兩個演算法, 然後對其進行分析.

//深度優先遍歷圖G中所有結點 
DFS(G)
	time = 0
	for G中每個結點v
		v.color = WHITE
	for G中每個結點v
		if v.color == WHITE
			v.p = NIL//NIL表示空 
			DFS_visit(v)

//深度優先遍歷所有G中從點v可達, 且為白色的結點 
DFS_visit(v, G)
	v.d = ++time
	v.color = GRAY
	for G中以v為起點的所有邊的終點u//若G為無向圖, 則為G中所有與v鄰接的結點u 
		if u.color == WHITE
			u.p = v
			DFS_visit(u)
	v.f = ++time
	v.color = BLACK 

    結論1: 演算法DFS(G)必定在執行有限次數後終止(根據執行完第4至5行的迴圈體之後G中所有結點被設為白色, 且每對一個結點a呼叫DFS_visit(a), a立即被設定為灰色即可證明結論1, 此處不再贅述證明過程)

    結論2(白色路徑定理): 演算法DFS_visit(v, G)將訪問G中所有結點u, 其中u滿足: 存在從v到u均為白色結點構成的路徑

    證明: 假設執行完DFS_visit(G, v)後, G中存在某個呼叫DFS_visit(G, v)初始時刻從從v到b均為白色結點構成的路徑的結點b沒有被訪問, 設c_{1}...c_{k}為a到b均由白色結點構成的路徑, c_{1}=v, c_{k}=b, 由第15至18行程式碼易知如果c_{k}

不被訪問, 那麼c_{k - 1}也不會被訪問, 一般的如果c_{i}(2 <= i <= k)不被訪問那麼c_{i - 1}也不會被訪問, 因此c_{1}=v不會被訪問, 這顯然與執行DFS_visit(G, v)矛盾, 因此假設不成立, 結論2得證.

    結論3(括號化定理): 對於圖G中任意兩個節點u, v滿足:

    (1)u.f < v.d

    (2)v.d < u.d < u.f < v.f

    (3)u.d < v.d < v.f < u.f

    (4)v.f < u.d

    上述(1), (2), (3), (4)必居其一切僅居其一. (根據結論2較易證明此結論的正確性, 此處不再贅述證明過程)  

    結論4: 設有向圖G{}'的結點集為G中所有結點構成的集合, 邊集為{<u, v> | u.p = v}, 則G{}'為森林, 且當G為無向圖時, G的每個連通分量中的結點對應G{}'中一個連通分量中的結點, 反之成立, 特別的, 演算法DFS_visit(v, G)將建立G{}'的一棵子樹.(根據結論2較易證明結論4, 此處不再贅述證明過程)

    結論5: 引入結論4定義的有向圖G{}', 並將G{}'中的邊成為樹邊, 每次第15行探索圖G的一條邊時, v為灰色, 對結點u的顏色分類, 滿足如下結論

    (1)u為白色, 則<v, u>為一條樹邊

    (2)u為灰色, 稱<v, u>為一條後向邊, 在G{}'中u為v的祖先, 如果圖G中存在環, 那麼第15行必定發現後向邊

    (3)u為黑色, 稱<v, u>為一條橫向邊, 則v, u在G{}'中位於兩棵樹中或者v, u在G{}'中位於一棵樹中且u為v的後代, 或者u不是v的後代, v也不是u的後代.

    證明: 根據之前的結論2和結論4較易結論5的正確性, 此處不再贅述證明過程

    結論6: 演算法DFS的時間複雜度為O(v + e), v為G中結點個數, e為G中邊的個數(證明從略)