廣度(BFS)和深度(DFS)優先算法這倆個算法是圖論里面非常重要的兩個遍歷的方法。
下面一個例子迷宮計算,如下圖
解釋:
所謂廣度,就是一層一層的,向下遍歷,層層堵截,看下面這幅圖,我們如果要是廣度優先遍歷的話,我們的結果是V1 V2 V3 V4 V5 V6 V7 V8。
廣度優先搜索的思想:
① 訪問頂點vi ;
② 訪問vi 的所有未被訪問的鄰接點w1 ,w2 , …wk ;
③ 依次從這些鄰接點(在步驟②中訪問的頂點)出發,訪問它們的所有未被訪問的鄰接點; 依此類推,直到圖中所有訪問過的頂點的鄰接點都被訪問;
說明:
為實現③,需要保存在步驟②中訪問的頂點,而且訪問這些頂點的鄰接點的順序為:先保存的頂點,其鄰接點先被訪問。 這里我們就想到了用標准模板庫中的queue隊列來實現這種先進現出的服務。
步驟:
1.將V1加入隊列,取出V1,並標記為true(即已經訪問),將其鄰接點加進入隊列,則 <—[V2 V3]
2.取出V2,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[V3 V4 V5]
3.取出V3,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[V4 V5 V6 V7]
4.取出V4,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[V5 V6 V7 V8]
5.取出V5,並標記為true(即已經訪問),因為其鄰接點已經加入隊列,則 <—[V6 V7 V8]
6.取出V6,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[V7 V8]
7.取出V7,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[V8]
8.取出V8,並標記為true(即已經訪問),將其未訪問過的鄰接點加進入隊列,則 <—[]
區別:
深度優先遍歷:對每一個可能的分支路徑深入到不能再深入為止,而且每個結點只能訪問一次。不全部保留結點,占用空間少;有回溯操作(即有入棧、出棧操作),運行速度慢。
廣度優先遍歷:又叫層次遍歷,從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。保留全部結點,占用空間大; 無回溯操作(即無入棧、出棧操作),運行速度快。
時間復雜度:
深度優先
數組表示:查找所有頂點的所有鄰接點所需時間為O(n2),n為頂點數,算法時間復雜度為O(n2)
廣度優先
數組表示:查找每個頂點的鄰接點所需時間為O(n2),n為頂點數,算法的時間復雜度為O(n2)