广度优先遍历-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

原文地址:https://www.cnblogs.com/ybf-yyj/p/9038072.html

时间: 2024-11-07 20:40:04

广度优先遍历-BFS、深度优先遍历-DFS的相关文章

二叉树的遍历之 深度优先(DFS)和广度优先(BFS)

深度优先遍历: 深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止. 如图所示的二叉树: A 是第一个访问的,然后顺序是 B.D,然后是 E.接着再是 C.F.G. 那么,怎么样才能来保证

图的广度优先遍历和深度优先遍历

图是一种很重要的数据结构,在我们的编程生活中应用极其广泛 #include <iostream> using namespace std; #define INFINITY 32767 #define MAX_VEX 20 //最大顶点个数 #define QUEUE_SIZE (MAX_VEX+1) //队列长度 bool *visited; //访问标志数组 //图的邻接矩阵存储结构 typedef struct { char *vexs; //顶点向量 int arcs[MAX_VEX]

python实现图广度优先遍历、深度优先遍历

一.广度优先遍历-bfs 顾名思义,bfs总是先访问完同一层的结点,然后才继续访问下一层结点,它最有用的性质是可以遍历一次就生成中心结点到所遍历结点的最短路径,这一点在求无权图的最短路径时非常有用.广度优先遍历的核心思想非常简单,用python实现起来也就十来行代码.下面就是超精简的实现,用来理解核心思想足够了: 1 import queue 2 3 def bfs(adj, start): 4 visited = set() 5 q = queue.Queue() 6 q.put(start)

广度优先遍历和深度优先遍历

对于二叉树,树的遍历通常有4种:先序遍历,中序遍历,后序遍历. 对于多叉树,树的遍历通常有2种,深度优先遍历和广度优先遍历 Dom的操作跟树的遍历天然的联系起来. 例如:上图所示的Dom树的关系可看出成一颗多叉树, 它的广度优先遍历(层次遍历)为: 深度优先遍历为:div .root  div .container  section .sidebar  ui.menu  section .mian  aritcle.post   p.copyright 例题: 利用深度优先遍历算法遍历出dom树

java实现图的遍历(深度优先遍历和广度优先遍历)

package arithmetic.graphTraveral;import java.util.LinkedList;import java.util.Queue; /** * 这个例子是图的遍历的两种方式 * 通过它,使我来理解图的遍历 * Created on 2013-11-18 * @version 0.1 */public class GraphTraveral{ // 邻接矩阵存储图 // --A B C D E F G H I // A 0 1 0 0 0 1 1 0 0 //

二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式

二叉树的遍历方式: 1.深度优先:递归,非递归实现方式 1)先序遍历:先访问根节点,再依次访问左子树和右子树 2)中序遍历:先访问左子树,再访问根节点吗,最后访问右子树 3)后序遍历:先访问左子树,再访问右子树,最后访问根节点 2.广度优先     按照树的深度,一层一层的访问树的节点 1 package Solution; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Stack; 6

图的邻接表(广度优先遍历,深度优先遍历,最小生成树(Kruskal算法))

main.h: #include <iostream> #include <queue> #define DefaultSize 10 #define maxWeight -1 using namespace std; template<typename T,typename E> struct Edge { int dest; E cost; Edge<T,E> *link; Edge(int d=0,int c=0):dest(d),cost(c),li

C++ 二叉树深度优先遍历和广度优先遍历

二叉树的创建代码==>C++ 创建和遍历二叉树 深度优先遍历:是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. //深度优先遍历二叉树void depthFirstSearch(Tree root){ stack<Node *> nodeStack; //使用C++的STL标准模板库 nodeStack.push(root); Node *node; while(!nodeStack.empty()){ node = nodeStack.top(); printf(format, n

转:二叉树的深度优先遍历和广度优先遍历

转自:http://www.blogjava.net/fancydeepin/archive/2013/02/03/395073.html 深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为