iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0

BFS全名Breadth-first search中文叫「廣度優先搜尋」,我個人覺得比DFS還要好理解很多,也因為他是「廣度」優先的原因,感覺就像「擴散」開來的感覺,以下我們就用Tree來感受一下BFS跟DFS的差別吧!
https://ithelp.ithome.com.tw/upload/images/20220927/20151772kCDRQXyZy7.png

實作BFS

在實作BFS的時候我們會使用Queue,還記的DFS因為是用Stack來實作的關係我們可以使用迴圈的Call Stack或是一般的Stack,但是Queue就只能直接在程式碼裡面撰寫沒有那種類似Call Stack的東西可以用囉。

以樹來說,一開始會把root加進我們的Queue,然後從Queue裡面Pop出來,再分別把左右節點放進Queue裡面,然後我們再把Queue裡剛加進的左右節點Pop出來,把他們相對應的子節點再加入Queue中,一直持續以上的動作一直到我們Queue為空,這樣就完成我們的BFS囉!
https://ithelp.ithome.com.tw/upload/images/20220927/20151772ENP23LcviT.png

BFS使用時機

上一篇我們說到DFS時有說到,很多情況下DFS跟BFS都可以處理,但BFS更擅長於處理每一「層」的這種問題,也因為我們要存的是層的資料所以記憶體有時候會用的多一點,想想看在Tree的結構裡面,DFS最多只會需要樹的高度的記憶體空間,但是BFS會需要整層節點數的空間,節點數是會比樹高度還要多的。
https://ithelp.ithome.com.tw/upload/images/20220927/20151772pSOiOB8dR8.png
這邊我認為一樣大家先有這個概念比較重要,之後遇到的問題越來越多後就能夠更知道到底應該使用DFS還是BFS了。

如何知道我在BFS的第幾層?

這個問題是我當初在練習BFS遇到的問題,聽起來很白癡,但是如果能幫助到讀者那我覺得也相當有意義。
如果我們看剛剛講的最基本BFS的流程會發現,如果今天我希望是印出這個節點的值跟他在第幾階,我是沒辦法知道他在第幾階的,因為我們就是不斷pop然後append,我們無從得知這個節點是在第幾階。
那解決辦法其實很簡單,就是我可以用for迴圈去決定我在「這一層」要Pop多少次,那個多少次可以用len(queue)來去獲取。這邊提供給各位圖片跟程式碼做參考囉。
https://ithelp.ithome.com.tw/upload/images/20220927/20151772Qkhzuwky5F.png

        queue = deque()
        layer = 0
        if root:
            queue.append(root)
        while queue:
            level_res = []
            for _ in range(len(queue)):
                node = queue.popleft()
                print(node.val, layer)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            layer += 1

BFS當然也不只可以用在Tree,也可以用在圖,這邊我們就來看一下BFS搜圖的效果吧。
https://ithelp.ithome.com.tw/upload/images/20220927/20151772JlAAReB2CX.png


上一篇
演算法-DFS
下一篇
演算法-Dynamic Programming
系列文
從演算法到解題思路,以Python為例30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言