一、基本概念
1、定義
首先訪問出發點v,並將其標記為已訪問過;然后依次從v出發搜索v的每個鄰接點w。若w未曾訪問過,則以w為新的出發點繼續進行深度優先遍歷,直至圖中所有和源點v有路徑相通的頂點(亦稱為從源點可達的頂點)均已被訪問為止。
若此時圖中仍有未訪問的頂點,則另選一個尚未訪問的頂點作為新的源點重復上述過程,直至圖中所有頂點均已被訪問為止。
2、特點
類似於樹的前序遍歷,盡可能先對縱深方向進行搜索。
3、基本思想
(1)訪問頂點v;
(2)從v的未被訪問的鄰接點中選取一個頂點w,從w出發進行深度優先遍歷;
(3)重復上述兩步,直至圖中所有和v有路徑相通的頂點都被訪問到。
4、偽代碼
遞歸實現:
(1)訪問頂點v;visited[v]=1;//算法執行前visited[n]=0
(2)w=頂點v的第一個鄰接點;
(3)while(w存在)
if(w未被訪問)
從頂點w出發遞歸執行該算法;
w=頂點v的下一個鄰接點;
非遞歸實現:(結合棧)
(1)棧S初始化;visited[n]=0;
(2)訪問頂點v;visited[v]=1;頂點v入棧S
(3)while(棧S非空)
x=棧S的頂元素(不出棧);
if(存在並找到未被訪問的x的鄰接點w)
訪問w;visited[w]=1;
w進棧;
else
x出棧;
5、實現
輸入圖像:
A
/ \
B C
/ \ / \
D E F--G
\ /
H
程序:
N = 8 visited = [0] * N stack = [] Graphic = [[0,1,1,0,0,0,0,0],[1,0,0,1,1,0,0],[1,0,0,0,0,1,1,0],[0,1,0,0,0,0,0,1],[0,1,0,0,0,0,0,1],[0,0,1,0,0,0,1,0],[0,0,1,0,0,1,0,0],[0,0,0,1,1,0,0,0]] def unvisited(x): for v in range(N): if visited[v] == 0 and Graphic[x][v] == 1: return v return -1 for v in range(N): if visited[v] == 0: print v visited[v] = 1 stack.append(v) while len(stack) > 0: x = stack[-1] w = unvisited(x) if w != -1: print w visited[w] = 1 stack.append(w) else: stack.pop() print
二、一些定理
運行時間:O(V+E),其中V是圖中的頂點,E是圖中的邊。
定理一(括號定理):解釋了圖中任意兩點u,v在深度優先搜索森林中可能的關系
a. u是v的后裔,則[d(u),f(u)]是[d(v),f(v)]的子區間
b.v是u的后裔,則[d(v),f(v)]是[d(u),f(u)]的子區間
c.u和v完全不相交,[d(u),f(u)]與[d(v),f(v)]不相關
三、回溯與剪枝:解答樹的深度優先搜索
例子:八皇后問題
