對於搜尋來說,我們絕大多數情況下處理的都是叫「所謂的暴力搜尋」,或者是說比較簡單樸素的搜尋,也就是說你在搜尋的時候沒有任何所謂的智慧型的情況在裡面考慮,很多情況下它做的一件事情就是把所有的結點全部遍歷一次,然後找到你要的結果。
基於這樣的乙個資料結構,如果這個資料結構本身是沒有任何特點的,也就是說是乙個很普通的樹或者很普通的圖。那麼我們要做的一件事情就是遍歷所有的結點。同時保證每個點訪問一次且僅訪問一次,最後找到結果。
那麼我們先把搜尋整個先化簡情況,我們就收縮到在樹的這種情況下來進行搜尋。
如果我們要找到我們需要的乙個值,在這個樹裡面我們要怎麼做?那麼毫無疑問就是從根這邊開始先搜左子樹,然後再往下乙個乙個乙個乙個點走過去,然後走完來之後再走右子樹,直到找到我們的點,這就是我們所採用的方式。
再回到我們資料結構定義,它只有左子樹和右子樹。
我們要實現這樣乙個遍歷或者搜尋的話,毫無疑問我們要保證的事情就是
僅訪問一次的意思就是代表我們在搜尋中,我們不想做過多無用的訪問,不然的話我們的訪問的效率會非常的慢。遞迴寫法遞迴的寫法,一開始就是遞迴的終止條件,然後處理當前的層,然後再下轉。
二叉樹模版
def dfs(node):
if node in visited:
# already visited
return
visited.add(node)
# process current node
# ... # logic here
dfs(node.left)
dfs(node.right)
多叉樹模版
visited = set()
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
永遠最先開始的,接下來往那個分支走其實都一樣的,我們簡單起見就是從最左邊開始走,那麼它深度優先的話就會走到底。
參考多叉樹模版我們可以在腦子裡面或者畫乙個圖把它遞迴起來的話,把遞迴的狀態樹畫出來,就是這麼乙個結構。
圖的遍歷順序
1
這個位置,然後它的水波紋一層一層一層擴散出去就行了。
兩者對比
bfs**模版
深度優先遍歷 和 廣度優先遍歷
圖的廣度優先搜尋是樹的按層次遍歷的推廣,它的基本思想是 首先訪問初始點vi,並將其標記為已訪問過,接著訪問vi的所有未被訪問過的鄰接點 vi1,vi2,vi t,並均標記已訪問過,然後再按照vi1,vi2,vi t的次序,訪問每乙個頂點的所有未被訪問過的鄰接點,並均標記為已訪問過,依次類推,直到圖中...
廣度優先遍歷和深度優先遍歷
深度優先遍歷 廣度優先遍歷是圖的一種遍歷方式,它的思想就是遍歷這個點相鄰的所有的點,再對這些點進行廣度優先遍歷.如下圖所示 首先我們從a點開始遍歷,然後遍歷所有和a相鄰的點f和點g 然後對f和點g進行遍歷進行遍歷,得到點e,h,k和b 然後再繼續,知道所有的點都遍歷完成 首先,我們先定義圖graph...
廣度優先遍歷和深度優先遍歷
1.1 概念 以初始節點v0作為第一層節點,接著訪問它。然後迭代第一層節點即v0,訪問它相鄰接的沒有訪問過的節點比如v1,v2,v1,v2加入到第二層節點 迭代第二層節點v1,v2,v1,v2依次訪問相鄰接的沒有訪問過的節點,重複上述步驟直至所有節點都被訪問過為止。如圖所示首先訪問根節點v0,並將v...