数据结构-深度优先遍历和广度优先遍历(漫画)
?
?
—————? 第二天? —————
?
?
?
————————————
?
?
?
?
什么是 深度/廣度 優(yōu)先遍歷?
深度優(yōu)先遍歷簡稱DFS(Depth First Search),廣度優(yōu)先遍歷簡稱BFS(Breadth First Search),它們是遍歷圖當中所有頂點的兩種方式。
這兩種遍歷方式有什么不同呢?我們來舉個栗子:
我們來到一個游樂場,游樂場里有11個景點。我們從景點0開始,要玩遍游樂場的所有景點,可以有什么樣的游玩次序呢?
?
第一種是一頭扎到底的玩法。我們選擇一條支路,盡可能不斷地深入,如果遇到死路就往回退,回退過程中如果遇到?jīng)]探索過的支路,就進入該支路繼續(xù)深入。
在圖中,我們首先選擇景點1的這條路,繼續(xù)深入到景點7、景點8,終于發(fā)現(xiàn)走不動了(景點旁邊的數(shù)字代表探索次序):
于是,我們退回到景點7,然后探索景點10,又走到了死胡同。于是,退回到景點1,探索景點9:
按照這個思路,我們再退回到景點0,后續(xù)依次探索景點2、3、5、4、6,終于玩遍了整個游樂場:
像這樣先深入探索,走到頭再回退尋找其他出路的遍歷方式,就叫做深度優(yōu)先遍歷(DFS)。
除了像深度優(yōu)先遍歷這樣一頭扎到底的玩法以外,我們還有另一種玩法:首先把起點相鄰的幾個景點玩遍,然后去玩距離起點稍遠一些(隔一層)的景點,然后再去玩距離起點更遠一些(隔兩層)的景點......
在圖中,我們首先探索景點0的相鄰景點1、2、3、4:
?
接著,我們探索與景點0相隔一層的景點7、9、5、6:
?
最后,我們探索與景點0相隔兩層的景點8、10:
?
像這樣一層一層由內而外的遍歷方式,就叫做廣度優(yōu)先遍歷(BFS)。
?
深度/廣度優(yōu)先遍歷 的實現(xiàn)
?
深度優(yōu)先遍歷
首先說說深度優(yōu)先遍歷的實現(xiàn)過程。這里所說的回溯是什么意思呢?回溯顧名思義,就是自后向前,追溯曾經(jīng)走過的路徑。
我們把剛才游樂場的例子抽象成數(shù)據(jù)結構的圖,假如我們依次訪問了頂點0、1、7、8,發(fā)現(xiàn)無路可走了,這時候我們要從頂點8退回到頂點7。
而后我們探索了頂點10,又無路可走了,這時候我們要從頂點10退回到頂點7,再退回到頂點1。
?
像這樣的自后向前追溯曾經(jīng)訪問過的路徑,就叫做回溯。
要想實現(xiàn)回溯,可以利用棧的先入后出特性,也可以采用遞歸的方式(因為遞歸本身就是基于方法調用棧來實現(xiàn))。
下面我們來演示一下具體實現(xiàn)過程。
首先訪問頂點0、1、7、8,這四個頂點依次入棧,此時頂點8是棧頂:
從頂點8退回到頂點7,頂點8出棧:
接下來訪問頂點10,頂點10入棧:
從頂點10退到頂點7,從頂點7退到頂點1,頂點10和頂點7出棧:
?
探索頂點9,頂點9入棧:
以此類推,利用這樣一個臨時棧來實現(xiàn)回溯,最終遍歷完所有頂點。
廣度優(yōu)先遍歷
接下來該說說廣度優(yōu)先遍歷的實現(xiàn)過程了。剛才所說的重放是什么意思呢?似乎聽起來和回溯差不多?其實,回溯與重放是完全相反的過程。
仍然以剛才的圖為例,按照廣度優(yōu)先遍歷的思想,我們首先遍歷頂點0,然后遍歷了鄰近頂點1、2、3、4:
接下來我們要遍歷更外圍的頂點,可是如何找到這些更外圍的頂點呢?我們需要把剛才遍歷過的頂點1、2、3、4按順序重新回顧一遍,從頂點1發(fā)現(xiàn)鄰近的頂點7、9;從頂點3發(fā)現(xiàn)鄰近的頂點5、6。
像這樣把遍歷過的頂點按照之前的遍歷順序重新回顧,就叫做重放。同樣的,要實現(xiàn)重放也需要額外的存儲空間,可以利用隊列的先入先出特性來實現(xiàn)。
下面我們來演示一下具體實現(xiàn)過程。
首先遍歷起點頂點0,頂點0入隊:
接下來頂點0出隊,遍歷頂點0的鄰近頂點1、2、3、4,并且把它們入隊:
然后頂點1出隊,遍歷頂點1的鄰近頂點7、9,并且把它們入隊:
然后頂點2出隊,沒有新的頂點可入隊:
以此類推,利用這樣一個隊列來實現(xiàn)重放,最終遍歷完所有頂點。
?
?- ?
?
以上內容來自《漫畫算法》
</div>總結
以上是生活随笔為你收集整理的数据结构-深度优先遍历和广度优先遍历(漫画)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 洛谷 P2089 烤鸡
- 下一篇: Java实现搜索回溯经典题目