一、用途
廣度優先算法是為了解決兩樣東西之間的最短距離,其中最短距離的含義很多,如:
- 編寫國際跳棋AI,計算最少走多少步就可獲勝
- 編寫拼寫檢查器, 計算最少編輯多少個地方就可將錯拼的單詞改成正確的單詞
- 根據你的人際關系網絡找到關系最近的醫生
二、圖
圖由節點和邊組成,模擬一組鏈接。
三、廣度優先搜索
應用場景
- 從節點A出發,有前往節點B的路徑嗎?
- 從節點A出發,前往節點B的哪條路徑最短?
問題:你經營着一個芒果農場,你要找一個芒果銷售商並把芒果賣給他。
解決思路:你需要優先從你的朋友中開始找,朋友中沒有,再從朋友的朋友中找,在找完所有朋友之前,不去找朋友的朋友。以此類推。如下圖所示:

這就需要按順序進行添加,並按順序進行查找,有一種數據結構可以實現這個目的,就是隊列。
四、隊列(Queues)
隊列的工作原理就和在醫院排隊掛號一張,排在前面的先掛號。
隊列是一種先進先出(First In First Out)的數據結構,而棧是一種后進先出(Last In First Out,LIFO)的數據結構。
隊列圖示:

五、有向圖和無向圖

有箭頭指向自己,但是沒有從自己指向其他人的箭頭,這被稱為有向圖(directed graph),其中的關系是單向的。 (Anuj、Peggy、Thom、Jonny)
直接相連的節點互為鄰居,被稱為無向圖。

六、實現算法
from collections import deque graph = {} graph['you'] = ['alices', 'bobs', 'claires'] graph['bobs'] = ['anujs', 'peggys'] graph['alices'] = ['peggys'] graph['claires'] = ['thoms', 'jonnys', 'jack'] graph['anujs'] = [] graph['peggys'] = [] graph['thoms'] = [] graph['jonnys'] = [] graph['jack'] = ['lucy', 'mango_andrew'] graph['lucy'] = [] graph['mango_andrew'] = [] def person_is_seller(name): return 'mango' in name def search(name): search_queue = deque() search_queue += graph[name] searched = [] while search_queue: person = search_queue.popleft() if person not in searched: if person_is_seller(person): print(person[6:] + ' is a mongo seller') return True else: search_queue += graph[person] searched.append(person) print('Not find mango seller') return False search('you')
順便提一下,字典這么寫是為了看起來更清晰,它的添加順序對結果是沒有影響的,因為散列表是無序的。
graph['you'] = ['alices', 'bobs', 'claires'] graph['bobs'] = ['anujs', 'peggys'] # 寫成下面這樣對結果一點影響都沒有 graph['bobs'] = ['anujs', 'peggys'] graph['you'] = ['alices', 'bobs', 'claires']

七、運行時間
你在整個人際關系網中搜索芒果銷售商,就意味着你需要沿每條邊前行(一個人到另一個人的箭頭),時間至少為O(邊數)。將每一個人添加到隊列的時間是O(1),因此廣度搜索的運行時間為O(人數 + 邊數),通常寫作O(V+E),其中V為定點(vertice),E為邊數。

