學習資料結構 - 深度優先搜尋 DFS 記錄

King發表於2024-05-11

深度優先搜尋(Depth-First Search,DFS)是一種用於遍歷或搜尋樹和圖的演算法。在最壞的情況下,深度優先搜尋的效能為 O(V+E),其中 V 是頂點數,E 是邊數。DFS 常用於解決連通性問題、路徑問題、生成樹問題等。

DFS 的使用步驟

  1. 初始化:建立一個資料結構(如棧)來儲存遍歷過程中訪問的節點。

  2. 訪問起始節點:將起始節點新增到棧中,並標記為已訪問。

  3. 探索鄰居:從棧頂取出一個節點,檢查其所有未訪問的鄰居節點。

  4. 遞迴或迭代:對每一個未訪問的鄰居節點,將其新增到棧中,並將其標記為已訪問。

  5. 重複探索:重複步驟 3 和 4,直到棧為空。

  6. 結束條件:當棧為空且沒有更多節點可以訪問時,搜尋結束。

DFS 的實現

DFS 可以用遞迴或非遞迴(迭代)的方式實現。

遞迴實現

def dfs(graph, node, visited=None):
    if visited is None:
        visited = set()
    visited.add(node)
    print(node)  # 處理節點
    for neighbour in graph[node]:
        if neighbour not in visited:
            dfs(graph, neighbour, visited)
    return visited

非遞迴實現(使用棧)

def dfs_iterative(graph, start):
    visited = set()
    stack = [start]

    while stack:
        node = stack.pop()
        if node not in visited:
            print(node)  # 處理節點
            visited.add(node)
            stack.extend(graph[node] - visited)  # 新增未訪問的鄰居到棧中
    return visited

DFS 的深度最佳化

  1. 剪枝:在搜尋過程中,如果確定某個節點不可能產生有效結果,可以提前終止對該節點的搜尋。

  2. 啟發式搜尋:在搜尋過程中使用啟發式資訊來指導搜尋方向,減少搜尋空間。

  3. 迭代加深:結合 DFS 和 BFS 的優點,透過限制搜尋深度來減少記憶體使用,並在必要時增加深度。

  4. 使用點陣圖或雜湊表:使用點陣圖或雜湊表來快速檢查節點是否已訪問。

  5. 最佳化鄰接表儲存:使用合適的資料結構來儲存圖的鄰接表,如鄰接表或鄰接矩陣,根據實際情況選擇。

  6. 並行搜尋:在多處理器或多執行緒環境中,可以並行地執行 DFS 搜尋。

實戰案例

假設我們要在一個圖中找到一個節點到另一個節點的路徑。

  1. 構建圖:首先,根據問題描述構建圖的鄰接表。

  2. 呼叫 DFS:從起始節點開始呼叫 DFS 函式。

  3. 回溯:在 DFS 中,如果當前路徑包含了目標節點,記錄路徑並回溯。

  4. 路徑恢復:透過回溯過程,可以從棧或遞迴呼叫鏈中恢復路徑。

透過 DFS,可以有效地找到圖中的路徑,解決許多圖論問題。在實際應用中,根據問題的特點和約束,可以對 DFS 進行適當的最佳化,以提高搜尋效率。本篇只是入門級的,更深層次的應用,後面會持續更新,歡迎大家提意見!!!

相關文章