# python實現圖的廣度優先搜素算法並打印最短路徑

``````from collections import deque

def create_graph():
"""採用鄰接表方式儲存圖"""
graph = {}
graph['A'] = ['B', 'C']
graph['B'] = ['D']
graph['C'] = ['E']
graph['D'] = []
graph['E'] = ['D']
return graph

def search(graph, start, target):
"""
廣度優先搜索，從stat起始到target是否有路徑，並打印最短路徑
:param graph: 圖
:param start: 起始點
:param target: 目標點
:return: 是否存在
"""
print("start :" + start)

# 創建一個隊列用於廣度優先搜索
search_queue = deque()
search_queue += graph[start]

# 記錄已經被檢查的節點（防止閉環，死循環）
searched = [start]

# 如果隊列爲空，則該圖中沒有target
while search_queue:
# 先從隊列中取出一個節點
point = search_queue.popleft()
# 該節點如果沒被查找過，則進行檢查
if point not in searched:
# 如果該節點，爲target，則找到並打印最短路徑
if point == target:
print("search :" + point)
searched.append(point)
# 打印最短路徑
path = get_path(searched, graph)
print(" ".join(path))
return True
# 如果當前節點不是target，則把其鄰居入隊並把該節點加入被檢查列表中
else:
search_queue += graph[point]
searched.append(point)
print("not searched")
return False

def get_path(searched_list, graph):
"""
打印最短路徑（回溯法）
思路：從target往上回溯，
（1）判斷當前節點是否爲起始點，否則走（2），是則（4）
（2）循環被檢查點列表並尋找第一個爲當前節點的父節點，
（3）將父節點置爲當前節點並結束本次尋找，重新走（2）
（4）逆序列表則爲最短路徑
"""
print("searched: " + str(searched_list))
target = searched_list[-1]
path = [target]
while target != searched_list[0]:
for i in searched_list:
if target in graph[i]:
target = i
path.append(i)
break
return path[::-1]

if __name__ == '__main__':
graph = create_graph()
search(graph, 'A', 'E')

``````