1. 程式人生 > >TopSort(拓撲排序)中DFS和BFS的應用

TopSort(拓撲排序)中DFS和BFS的應用

深度優先搜尋:
下面圖中的數字顯示了深度優先搜尋頂點被訪問的順序。

為了實現深度優先搜尋,首先選擇一個起始頂點並需要遵守三個規則:
(1) 如果可能,訪問一個鄰接的未訪問頂點,標記它,並把它放入棧中。
(2) 當不能執行規則1時,如果棧不空,就從棧中彈出一個頂點。
(3) 如果不能執行規則1和規則2,就完成了整個搜尋過程。

廣度優先搜尋:
在深度優先搜尋中,演算法表現得好像要儘快地遠離起始點似的。相反,在廣度優先搜尋中,演算法好像要儘可能地靠近起始點。它首先訪問起始頂點的所有鄰接點,然後再訪問較遠的區域。它是用佇列來實現的。
下面圖中的數字顯示了廣度優先搜尋頂點被訪問的順序。

實現廣度優先搜尋,也要遵守三個規則:
(1) 訪問下一個未來訪問的鄰接點,這個頂點必須是當前頂點的鄰接點,標記它,並把它插入到佇列中。
(2) 如果因為已經沒有未訪問頂點而不能執行規則1時,那麼從佇列頭取一個頂點,並使其成為當前頂點。
(3) 如果因為佇列為空而不能執行規則2,則搜尋結束。


1.深度優先搜尋DFS(遞迴呼叫棧實現)

void DFS(graph *G, int v){
    G->setMark(v,VISITED);
    for(int w=G->first(v);w<G->n();w=G->next(v,w))
        if(G->getMark(w)==UNVISITED)
            DFS(G,w);
}


2.廣度優先搜尋BFS(優先佇列實現)

void BFS(graph *G, int  start, Queue<int> *Q)
{
    int v,w;
    Q->enqueue(start);
    G->setMark(start,VISITED);
    while(Q->lenght!=0)
    {
        Q->dequeue(v);
        for(w->G->first(v);w<G->n();w=G->next(v,w))
            if(G->getMark(w)==UNVISITED){
                G->setMark(w)= VISITED;
                Q->enqueue(w);
            }
    }
}

下圖摘自嚴蔚敏的教材:

上面說的是DFS。

我們通常會在u對所有的v搜尋完後把vis[u]=0;表示未訪問,可能會在另一條路徑中訪問到u,對此,可以這樣理解在沒有環的情況下,訪問的複雜度算邊x->u的

下面說的是BFS。