1. 程式人生 > >廣度優先遍歷-BFS、深度優先遍歷-DFS

廣度優先遍歷-BFS、深度優先遍歷-DFS

lse rim cnblogs return 直接 ref 生成 init www.

廣度優先遍歷-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