1. 程式人生 > >判斷無向圖和有向圖是否有迴路

判斷無向圖和有向圖是否有迴路

一、無向圖迴路的判斷

    對於無向圖,判斷其是否有迴路有四種方法,如下所示:

    1、利用深度優先搜尋DFS,在搜尋過程中判斷是否會出現後向邊(DFS中,連線頂點u到它的某一祖先頂點v的邊),即在DFS對頂點進行著色過程中,若出現所指向的頂點為黑色,則此頂點是一個已經遍歷過的頂點(祖先),出現了後向邊,若完成DFS後,則圖中有迴路;

    2、在圖的鄰接表表示中,首先統計每個頂點的度,然後重複尋找一個度為1的頂點,將度為1和0的頂點從圖中刪除,並將與該頂點相關聯的頂點的度減1,然後繼續反覆尋找度為1的,在尋找過程中若出現若干頂點的度都為2,則這些頂點組成了一個迴路;否則,圖中不存在迴路。

    3、利用BFS,在遍歷過程中,為每個節點標記一個深度deep,如果存在某個節點為v,除了其父節點u外,還存在與v相鄰的節點w使得deep[v]<=deep[w]的,那麼該圖一定存在迴路;
    4、用BFS或DFS遍歷,最後判斷對於每一個連通分量當中,如果邊數m>=節點個數n,那麼改圖一定存在迴路。因此在DFS或BFS中,我們可以統計每一個連通分量的頂點數目n和邊數m,如果m>=n則return false;直到訪問完所有的節點,return true。

二、有向圖迴路的判斷

    對於有向圖,判斷其是否有迴路的方法也有兩種,如下所示:

    1、與無向圖類似,若在DFS中出現後向邊,即存在某一頂點被第二次訪問到,則有迴路出現;

    2、同樣,利用拓撲排序的思想,通過這一步驟來執行拓撲排序,即重複尋找一個入度為0的頂點,將該頂點從圖中刪除,並將該頂點及其所有的出邊從圖中刪除(即與該點相應的頂點的入度減1),最終若途中全為入度為1的點,則這些點至少組成一個迴路。

    對於有向圖,具體點就可得到如下分析:

    問題分析:如果圖中存在迴路,則必包含一個子圖為迴路。即該子圖中所有頂點入度不為0且至少有邊指向另外的頂點。
    演算法:
    步驟1:按鄰接表方式儲存圖。遍歷與每個節點關聯的邊並統計每個節點的入度。需要O(n+m)次的運算。
    步驟2:刪除所有入度為零的頂點及其相發出的邊。並將被刪除邊所指向的頂點的入度減1。
    重複步驟2直到:
    (1)所有頂點被刪除(則沒有迴路)或;
    (2)還有頂頂點但沒有入度為零的頂點可刪除(則存在迴路)。
    演算法複雜度分析:
    由於步驟二中的刪除邊的操作運算複雜度為O(m),刪除節點的操作為O(n) 判斷節點入度是否為0需要O(n+m)次運算。其中O(n)次為初始入度為零的節點,O(m)次為刪除邊後導致的入度為零的節點。於是整個演算法複雜度為O(m+n)。