八数码深度优先搜索_深度优先搜索和广度优先搜索
深度優先搜索和廣度優先搜索
關于搜索&遍歷
對于搜索來說,我們絕大多數情況下處理的都是叫 “所謂的暴力搜索” ,或者是說比較簡單樸素的搜索,也就是說你在搜索的時候沒有任何所謂的智能的情況在里面考慮,很多情況下它做的一件事情就是把所有的結點全部遍歷一次,然后找到你要的結果。
基于這樣的一個數據結構,如果這個數據結構本身是沒有任何特點的,也就是說是一個很普通的樹或者很普通的圖。那么我們要做的一件事情就是遍歷所有的結點。同時保證每個點訪問一次且僅訪問一次,最后找到結果。
那么我們先把搜索整個先化簡情況,我們就收縮到在樹的這種情況下來進行搜索。
如果我們要找到我們需要的一個值,在這個樹里面我們要怎么做?那么毫無疑問就是從根這邊開始先搜左子樹,然后再往下一個一個一個一個點走過去,然后走完來之后再走右子樹,直到找到我們的點,這就是我們所采用的方式。
再回到我們數據結構定義,它只有左子樹和右子樹。
我們要實現這樣一個遍歷或者搜索的話,毫無疑問我們要保證的事情就是
- 每個結點都要訪問一次
- 每個結點僅僅要訪問一次
- 對于結點訪問的順序不限
- 深度優先:Depth First Search
- 廣度優先:Breadth First Search
僅訪問一次的意思就是代表我們在搜索中,我們不想做過多無用的訪問,不然的話我們的訪問的效率會非常的慢。
當然的話還可以有其余的搜索,其余的搜索的話就不再是深度優先或者廣度優先了,而是按照優先級優先 。當然你也可以隨意定義,比如說從中間優先類似于其他的東西,但只不過的話你定義的話要有現實中的場景。所以你可以認為是一般來說就是深度優先、廣度優先,另外的話就是優先級優先。按照優先級優先搜索的話,其實更加適用于現實中的很多業務場景,而這樣的算法我們一般把它稱為啟發式搜索,更多應用在深度學習領域。而這種比如說優先級優先的話,在很多時候現在已經應用在各種推薦算法和高級的搜索算法,讓你搜出你中間最感興趣的內容,以及每天打開抖音、快手的話就給你推薦你最感興趣的內容,其實就是這個原因。
深度優先搜索(DFS)
遞歸寫法
遞歸的寫法,一開始就是遞歸的終止條件,然后處理當前的層,然后再下轉。
- 那么處理當前層的話就是相當于訪問了結點 node,然后把這個結點 node 加到已訪問的結點里面去;
- 那么終止條件的話,就是如果這個結點之前已經訪問過了,那就不管了;
- 那么下轉的話,就是走到它的子結點,二叉樹來說的話就是左孩子和右孩子,如果是圖的話就是連同的相鄰結點,如果是多叉樹的話這里就是一個children,然后把所有的children的話遍歷一次。
if node in visited:
# already visited
return
visited.add(node)
# process current node
# ... # logic here
dfs(node.left)
dfs(node.right)
def dfs(node, visited):
if node in visited: # terminator
# already visited
return
visited.add(node)
# process current node here.
...
for next_node in node.children():
if next_node not in visited:
dfs(next_node, visited)
非遞歸寫法
def DFS(self, tree):if tree.root is None:
return []
visited, stack = [], [tree.root]
while stack:
node = stack.pop()
visited.add(node)
process (node)
nodes = generate_related_nodes(node)
stack.push(nodes)
# other processing work
...
遍歷順序
我們看深度優先搜索或者深度優先遍歷的話,它的整個遍歷順序毫無疑問根節點 1 永遠最先開始的,接下來往那個分支走其實都一樣的,我們簡單起見就是從最左邊開始走,那么它深度優先的話就會走到底。
參考多叉樹模版我們可以在腦子里面或者畫一個圖把它遞歸起來的話,把遞歸的狀態樹畫出來,就是這么一個結構。
- 就比如說它開始剛進來的話,傳的是 ?root 的話,root 就會先放到 visited 里面,表示 root 已經被 visit,被 visited之后就從 root.childern里面找 next_node,所有它的next_node都沒有被訪問過的,所以它就會先訪問最左邊的這個結點,這里注意當它最左邊這個結點先拿出來了,判斷沒有在 visited里面,因為除了 root之外其他結點都沒有被 visited過,那么沒有的話它就直接調dfs,next_node 就是把最左邊結點放進去,再把 visited也一起放進去。
- 遞歸調用的一個特殊,它不會等這個循環跑完,它就直接會進到下一層了,也就是當前夢境的話這里寫了一層循環,但是在第一層循環的時候,我就要開始下鉆到新的一層夢境里面去了。所以在這里的話,
圖的遍歷順序
廣度優先搜索(BFS)
廣度優先遍歷它就不再是用遞歸也不再是用棧了,而是用所謂的隊列。你可以把它想象成一個水滴,滴到1這個位置,然后它的水波紋一層一層一層擴散出去就行了。
兩者對比
BFS代碼模版
# Pythondef BFS(graph, start, end):
visited = set()
queue = []
queue.append([start])
while queue:
node = queue.pop()
visited.add(node)
process(node)
nodes = generate_related_nodes(node)
queue.push(nodes)
# other processing work
...
部分圖片來源于網絡,版權歸原作者,侵刪。
?點擊閱讀原文,查看往期內容!
快留言?和我互動吧~
總結
以上是生活随笔為你收集整理的八数码深度优先搜索_深度优先搜索和广度优先搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 化妆店铺名字大全好听创意282个
- 下一篇: 昆虫记读后感50字