數據結構筆記——圖的深度優先遍歷(DFS)

寫在前面:科班出身,應屆考研黨,願21考研成功上岸,沖沖衝!

目錄

一、樹的深度優先遍歷

二、圖的深度優先遍歷

三、算法存在的問題

五、複雜度分析

空間複雜度

時間複雜度

六、深度優先遍歷序列

七、深度優先生成樹

八、深度優先生成樹森林

九、圖的遍歷與圖的連通性

十、總結

一、樹的深度優先遍歷

void PreOrder(TreeNode *R){
    if(R != NULL){
        visit(R);
        while(R還有下一個子樹T)
            PreOrder(T);
    }
}

樹的深度優先遍歷(先根、後根):

從根節點出發,能往更深處走就走。每當訪問一個結點的時候,要檢查是否還有與當前結點相鄰的且沒有被訪問過的結點,如果有的話就往下一層鑽。

注:新找到的相鄰結點一定是沒有訪問過的

下圖先根遍歷序列:12563478

二、圖的深度優先遍歷

bool visited[MAX_VERTEX_NUM];    //訪問標記數組
void DFS(Graph G,int v){        //從頂點v出發,深度優先遍歷圖G
    visit(v);        //訪問頂點v
    visited(v) = TRUE;        //設已訪問標記
    for(w = FirstNeighbor(G,v); w >= 0; w = NextNeighbor(G,v,w))
        if(!visited[w])        //w爲u的尚未訪問的鄰接頂點
            DFS(G,w);
}

三、算法存在的問題

如果是非連通圖圖,則無法遍歷完所有結點

四、DFS算法(Final版)

bool visited[MAX_VERTEX_NUM];    //訪問標記數組

void DFSTraverse(Graph G){
    for(v = 0; v < G.vexnum;++v)
        visited[v] = FALSE;
    for(v = 0; v < G.vexnum;++v)
        if(!visited[v])
            DFS(G,v);
}

void DFS(Graph G,int v){        //從頂點v出發,深度優先遍歷圖G
    visit(v);        //訪問頂點v
    visited(v) = TRUE;        //設已訪問標記
    for(w = FirstNeighbor(G,v); w >= 0; w = NextNeighbor(G,v,w))
        if(!visited[w])        //w爲u的尚未訪問的鄰接頂點
            DFS(G,w);
}

五、複雜度分析

空間複雜度

最壞情況:遞歸深度爲O(|V|)

最好情況:O(1)

時間複雜度

時間複雜度=訪問各結點所需時間+探索各條邊所需時間

鄰接矩陣存儲的圖:

訪問|V|個頂點需要O(|V|)的時間

查找每個頂點的鄰接點都需要O(|V|)的時間,而總共有|V|個頂點

時間複雜度:O(|V|^2)

鄰接表存儲的圖:

訪問|V|個頂點需要O(|V|)的時間

查找各個頂點的鄰接點共需要O(|E|)的時間

查找各個頂點的鄰接點共需要O(|E|)的時間

時間複雜度= O(|V|+|E|)

六、深度優先遍歷序列

從2出發的深度優先遍歷序列:21563478

從3出發的深度優先遍歷序列:34762158

從1出發的深度優先遍歷序列:12634785

注:

同一個圖的鄰接矩陣表示方式唯一,因此深度優先遍歷序列唯一

同一個圖的鄰接表表示訪問不唯一,因此深度優先遍歷序列不唯一

七、深度優先生成樹

同一個圖的鄰接矩陣表示方式唯一,因此深度優先遍歷序列唯一,深度優先生成樹也唯一

同一個圖的鄰接表表示訪問不唯一,因此深度優先遍歷序列不唯一,深度優先生成樹也不唯一

八、深度優先生成樹森林

九、圖的遍歷與圖的連通性

無向圖進行BFS/DFS遍歷,調用BFS/DFS函數的次數=連通分量數

連通圖,只需調用1次BFS/DFS

有向圖進行BFS/DFS遍歷,調用BFS/DFS函數的次數要具體問題具體分析

若起始頂點到其他各頂點都有路徑,則只需調用1次BFS/DFS函數

強連通圖,從任一結點出發都只需調用1次BFS/DFS

十、總結

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章