廣度優先遍歷-BFS、深度優先遍歷-DFS
廣度優先遍歷-BFS
廣度優先遍歷類似與二叉樹的層序遍歷算法,它的基本思想是:首先訪問起始頂點v,接著由v出發,依次訪問v的各個未訪問的頂點w1 w2 w3....wn,然後再依次訪問w1 w2 w3....wn的所有未被訪問的鄰接頂點;再從這些訪問過的頂點出發,再訪問它們所有未被訪問過的鄰接頂點......依次類推,直到圖中的所有點都被訪問為止。類似的思想還將應用於Dijkstra單源最短路徑算法和Prim最小生成樹算法。
python實現二叉樹的建立以及遍歷(遞歸前序、中序、後序遍歷,隊棧前序、中序、後序、層次遍歷)中的樹的層序遍歷就用到了BFS的思想
深度優先遍歷-DFS
與廣度優先遍歷不同,深度優先遍歷類似於樹的先序遍歷,正如其名稱中所暗含的意思一樣,這種搜索算法所遵循的策略是盡可能“深”地搜索一下圖。它的基本思想如下:首先訪問圖中某一點頂點v,然後從v出發,訪問與v相鄰的點w1,再從w1出發訪問w1的鄰接點w2....重復上述過程,直到不能繼續訪問時,依次退回到最近的訪問點,若還有未訪問的鄰接點,從該節點出發,繼續上面的訪問過程。
下面以一個例題來展示BFS和DFS:
題目描述(2018春招-今日頭條筆試題-第二題)
定義兩個字符串變量:s和m,再定義兩個操作:
第一種操作:m=s s=s+s
第二種操作:s=s+m
假設s和m,初始如下:
s=‘a‘ m=s
求最小步驟數,可以將s拼接到長度等於n
輸入描述
一個整數n,表明我們需要得到s字符串長度,0<n<1000
輸出描述
一個整數,表明總共操作次數
輸入樣例:
輸入
6
輸出
3
說明:
輸入是6,表明我們需要得到s字符串長度為6,也就是s為最終為‘aaaaaa’,那麽依次使用2次“第一種操作”和1次“第二種操作”就能達到目的,總共操作次數是3
輸入
5
輸出
4
說明:
輸入是5,表明我們需要得到s字符串長度為5,也就是‘aaaaa’,那麽直接使用4次“第二種操作”就能達到目的,總共操作次數是4
BFS
#-*- coding:utf-8 -*- import datetime class BFS(object): def __init__(self): self.num = 0 def fun(self,s,m,n): stack=[[s,m]] stack_s=set()#用來存儲字符串s的長度 while True: if n in stack_s: break stack_temp=[] while stack: temp=stack.pop() temp_1=[2*temp[0],temp[0]] temp_2=[temp[0]+temp[1],temp[1]] stack_s.add(2 * temp[0]) stack_s.add(temp[0]+temp[1]) stack_temp.append(temp_1) stack_temp.append(temp_2) self.num+=1 stack=stack_temp if __name__==‘__main__‘: n = input() i = datetime.datetime.now() bfs = BFS() bfs.fun(1, 1,n) j = datetime.datetime.now() print bfs.num print j - i
輸入:
10000
輸出:
20
0:00:02.296000
DFS:
#-*- coding:utf-8 -*- import datetime class DFS(object): ‘‘‘ num:用於存儲最後執行次數 n:用於存儲最後達到的字符串的長度 flag:當達到輸入字符串的長度時,flag置為1 ‘‘‘ def __init__(self,n): self.num=0 self.n=n self.flag=0 def fun(self,s,m): self.fun_1(s,m) self.fun_2(s,m) #當未達到字符串長度時,回溯 if self.flag==0: self.num-=1 #fun_1:方法1 def fun_1(self,s,m): #當達到字符串長度,直接返回 if self.flag == 0: if self.n < s: return if self.n == s: self.flag = 1 return else: m = s s += s self.num += 1 #沒達到字符串長度,繼續遞歸 self.fun(s, m) else: return # fun_2:方法2 def fun_2(self,s,m): if self.flag == 0: if self.n<s: return if self.n==s: self.flag=1 return else: s=s+m self.num+=1 # 沒達到字符串長度,繼續遞歸 self.fun(s,m) else: return if __name__==‘__main__‘: n=input() i=datetime.datetime.now() dfs=DFS(n) dfs.fun(1,1) j = datetime.datetime.now() print dfs.num print j-i
輸入:
10000
輸出:
20
0:00:00.034000
廣度優先遍歷-BFS、深度優先遍歷-DFS