BFS 廣度優先搜尋

2021-09-05 09:25:54 字數 2862 閱讀 5488

近半年經常刷題,也參加了同學們自行組織的刷題會,到寫這篇文章為止 leetcode 已經 ac 了 77 道題目了。時常的總結是必要的,而分享知識不僅能幫助自己樹立知識脈絡,更能幫助到大家,為學習演算法的同學們提供一種參考的思路。

廣度優先搜尋(bfs)是在搜尋中首先將所處位置的直接鄰居訪問一遍,再進入下一層重複之前操作的一種搜尋。這種演算法需要維護乙個佇列。佇列有著先進先出(first in first out)的性質。演算法的開始一般都是把根節點加入到空佇列中,然後開始乙個結束條件是隊列為空的迴圈。每一次迴圈中,演算法會取得佇列最前的乙個元素並且訪問它的所有鄰居。在訪問鄰居的同時,程式會把鄰居新增到佇列中。至此廣度優先搜尋就寫完了,程式會按照上述迴圈把能夠訪問到的節點都訪問一遍。

這種演算法可以應用在圖,也可以應用在樹上。下面我們來看幾道跟樹這種資料結構有關的題目。

leetcode 429 這道題是典型的廣度優先搜尋,要求按層遍歷樹。解答如下:

"""

# definition for a node.

class node(object):

def __init__(self, val, children):

self.val = val

self.children = children

"""class

solution

(object):

deflevelorder

(self, root)

:"""

:type root: node

:rtype: list[list[int]]

"""if root is

none

:return

queue =

[(root,0)

] result =

while queue:

node, level = queue.pop(0)

while

len(result)

<= level:

) result[level]

for child in node.children:

(child, level +1)

)return result

我們規定根節點是第 0 層,然後把節點和所在層級放在乙個 tuple 裡進隊。迴圈的終止條件是隊列為空,當佇列有元素時,隊頭出隊,我們對元素做一些處理,然後將它的子孫加入佇列。在這個問題中,對於元素的操作比較簡單,把它加入結果陣列中即可。當然,加入之前要保證陣列對應的位置有陣列存在(結果是乙個包含陣列的陣列),不然會丟擲索引越界的異常。

leetcode 103 是一道中等難度的題目,要求交叉遍歷二叉樹。交叉的意思是從根節點開始,根節點那層從左到右遍歷,下一層從右到左,再下一層從左到右,依次迴圈直到最後一層,期間忽略 null.

# definition for a binary tree node.

# class treenode(object):

# def __init__(self, x):

# self.val = x

# self.left = none

# self.right = none

class

solution

(object):

defzigzaglevelorder

(self, root)

:"""

:type root: treenode

:rtype: list[list[int]]

"""if root is

none

:return

queue =

[(root,0,

true)]

result =

while queue:

node, level, left_to_right = queue.pop(0)

while

len(result)

<= level:

) nodes_on_same_level =

[node]

while

len(queue)

>

0and queue[0]

[1]== level:0)

[0])

for n in nodes_on_same_level:

if n.left:

(n.left, level +1,

not left_to_right)

)if n.right:

(n.right, level +1,

not left_to_right)

)if left_to_right:

for n in nodes_on_same_level:

result[level]

else

:for i in

range

(len

(nodes_on_same_level)-1

,-1,

-1):

n = nodes_on_same_level[i]

result[level]

return result

題目依舊是要求按層遍歷,所以廣度優先搜尋仍然是我選用的方法。於是讀者可以發現本題解法和上一題有著很類似的結構,也有人稱之為「套公式」。不同的第一處在於佇列中的 tuple 現在有三個元素了,增加了末尾的乙個布林型別。該布林變數值為 true 的時候說明當前層級需要從左往右遍歷,反之從右往左。在迴圈中,程式一次性將一層的節點全部找出,按照布林變數指定的順序新增到結果陣列中。剩下的工作就是將子節點進隊,和上一題同樣的是層級要加 1,不同的是要將布林變數扭轉後再存入佇列。

BFS廣度優先搜尋

廣度優先搜尋,利用佇列實現,結束標誌是隊列為空的時候 承接dfs的演算法實現的講例,對於迷宮問題我們也可以採取廣度優先搜尋實現 include iostream include cstdio include cstdlib using namespace std int map 55 55 int ...

bfs廣度優先搜尋

這一課我們來學習圖的另一種遍歷方法 廣度優先搜尋 breadth first search,簡稱 bfs 這是一種連通圖的常用遍歷策略,通常用於求起點到各點的最短路徑,以及求兩點之間的最優路徑等問題。首先我們先來看看廣度優先搜尋的具體方法吧 對於乙個連通圖,我們假設一開始所有頂點均未被訪問,廣度優先...

廣度優先搜尋bfs

bfs即廣度優先搜尋演算法,其是搜尋演算法中的一種。1.dfs常用於尋找是否存在解 其從a節點出發,選取乙個臨近點b,然後不斷深入,在搜尋完b的下屬節點 ehif 後,回到a再搜尋臨近a的c節點,以此類推。2.bfs則用於在最短的時間或最少的移動距離內找到解 其往往從a節點出發,搜尋周圍所有的圍繞節...