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


廣度優先遍歷-BFS

廣度優先遍歷類似與二叉樹的層序遍歷算法,它的基本思想是:首先訪問起始頂點v,接着由v出發,依次訪問v的各個未訪問的頂點www3....wn,然后再依次訪問www3....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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM