日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

06-广度优先搜索:图、队列

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 06-广度优先搜索:图、队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構和算法
基于《算法圖解》—Aditya Bhargava 和《數據結構》—嚴蔚敏

第6章廣度優先搜索

6.1 簡介
廣度優先搜索—breadth-first search,BFS.
主要內容圖和隊列。
廣度優先搜索能讓你能夠找出兩樣東西之間的最短距離,比如:編寫國際跳棋AI(Artificial Intelligence),計算最少走多少步可以獲勝;或者根據你的人際關系網絡找到關系最近的醫生。

需要兩個步驟:

(1)使用圖來建立問題模型。
(2)使用廣度優先搜索解決問題。

6.2 什么是圖
圖由節點和邊組成。一個節點可能與眾多節點直接相連,這些節點被稱為鄰居。

6.3 廣度優先搜索
廣度優先搜索是一種用于圖的查找算法,可幫助回答兩類問題:

  • 第一類問題:從節點A出發,有前往節點B的路徑嗎?
  • 第二類問題:從節點A出發,前往節點B的哪條路徑最短?

假設你經營著一個芒果農場,需要尋找芒果銷售商,以便將芒果賣給他。為此,你可在朋友中查找。

首先創建一個朋友名單,然后依次檢查名單中的每個人,是否是芒果銷售商:

假設你沒有朋友是芒果銷售商,那么你就必須在朋友的朋友中查找。

檢查名單中的每個人時,你都將其朋友加入名單。

6.3.1 查找最短路徑
一度關系勝過二度關系,二度關系勝過三度關系,以此類推。

廣度優先搜索不僅查找從A到B的路徑,而且找到的是最短的路徑。

只有按添加順序查找時,才能實現這樣的目的。

隊列(queue):實現按添加順序進行檢查的數據結構。

6.3.2 隊列
隊列能夠實現按添加順序進行檢查的需求。
隊列不能隨機訪問,只能支持兩種操作:入隊和出隊。

先加入的元素將先出隊并被檢查。

隊列是一種先進先出(First In First Out)的數據結構;
棧是一種后進先出(Last In First Out)的數據結構。

6.4 實現圖
圖是由多個節點組成,需要使用代碼來實現圖。
每個結點都與鄰近結點相連,散列表可以很好的實現這種關系。

散列表將鍵映射到值,比如將你這個節點映射到所有鄰居。

表示這種映射關系的Python代碼如下,

graph = {} #前面提到Python中是用字典來實現散列表。{}表示生成空字典。 graph["you"] = ["alice", "bob", "claire"] #"you"被映射到了一個數組,因此graph["you"]是一個數組,包含了"you"的所有鄰居。

graph = {} graph["you"] = ["alice", "bob", "claire"] graph["bob"] = ["anuj", "peggy"] graph["alice"] = ["peggy"] graph["claire"] = ["thom", "jonny"] graph["anuj"] = [] graph["peggy"] = [] graph["thom"] = [] graph["jonny"] = [] #散列表是無序的,因此添加鍵-值對的順序不關緊要。

有向圖(directed graph):有一個節點指向相鄰節點,單向關系。上圖中Anuj,Peggy,Thom,Jonny都沒有鄰居,因為他們沒有指向其他節點。

無向圖(undirected graph):沒有箭頭,直接連接的節點互為鄰居。
下面兩圖等效:

6.5 實現算法
隊列實現原理

#首先使用函數deque來創建一個雙端隊列。 from collections import deque 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 + "is a mango seller!")return Trueelse:search_queue += graph[person] #如果不是,將此人的朋友(相鄰節點)都加入搜索隊列。searched.append(person) #并將此人添加到以搜索過的列表,避免再次搜索此人。return False #如果到達這里,說明隊列中沒有芒果銷售商#假設以姓名結尾為m的人為芒果銷售商。 def person_is_seller(name):return name[-1] == 'm' #名字末尾為msearch("you") #函數調用

為什么要避免被重復搜索(檢查):
上圖中Peggy既是Alice的朋友又是Bob的朋友,因此她將被加入隊列兩次;因此,搜索隊列將包含兩個Peggy。

檢查完一個人后,應將其標記為已檢查,且不再檢查;如果不這樣做,就可能會導致無限循環。

因為搜索隊列將在包含你和包含Peggy之間反復切換,從而造成無限循環。

列表是有序的。如果任務A依賴于任務B,在列表中任務A就必須在任務B后面,這被稱為拓撲排序,使用它可根據圖創建一個有序表。

6.5.1 樹
樹是特殊的圖,其中沒有往后指的邊。

樹是圖的子集,樹都是圖,圖不一定是樹。

6.6 小結

  • 隊列是先進先出。
  • 棧是后進先出。
  • 注意避免導致無限循環。

——持續修改完善中…

總結

以上是生活随笔為你收集整理的06-广度优先搜索:图、队列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。