搜索算法 DFS 、BFS等 (python实现)(1)

搜索算法 BFS (python实现)

一、综述

遍历算法中最基础的就是 BFS 和 DFS 算法。本文将使用python,介绍BFS的中心思想和代码实现。后续将介绍各种遍历算法。

二、BFS

1.实现过程

BFS又称广度优先搜索,顾名思义,就是搜索注重广度。
例如下图:

假设有一只鹰在起始点A,“他”视野宽广,雄姿英发,正准备去寻找一只雌鸟喜结连理。但是雌鸟太胖飞不动,深藏草丛之中,所以它只能找遍所有的地方。这只鸟,每前进一次,就会将与他所在地相连的所有的地方全部找完。这里用涂色来代表他遍历的顺序。·

下面我们深入分析一下其中的实现过程,这里我引用“queue(队)”这个概念,队讲究先来后到,所以第一个排队的也就第一个出来。即先进先出原则。
对于上图,以下是具体实现过程

  1. A排进队中
  2. 与A相连的B,C,D排进队中
  3. B,C,D 其中一点相连的元素放入队中
    例如选择D,与D相连的则是E点)
  4. B,C点的相连的元素放入队中。
  5. 以此类推…直到找到他的新娘,或者队中没有元素(那么这是只孤鹰)

产生的队列就是这样----
A-B-C-D-E-F

由以上步骤可知,BFS的遍历是多种多样的。

2.代码实现

(1)遍历全图

graph = {'A':['B','C'],
         'B':['D','A'],
         'D':['B','C'],
         'C':['D','E','A'],
         'E':['D','C','F'],
         'F':['E']} 
#首先使用字典创建一个图

def BFS(graph,start):#函数以图和起点作为变量
	queue = [start]#起点首先排进队列
	alreadyTraverse = {start}#年轻的鹰的记性好,不会走相同的地方
	
	while (len(queue)>0):#不断遍历直到队中没有元素
		node=queue.pop(0)#取出队中的一个元素
		print(node)
		for neighbour in graph[node]:#对于选中元素的所有邻居进行遍历
			if neighbour not in alreadyTraverse:#集合在python中是hashing判断快
				alreadyTraverse.add(neighbour)
				queue.append(neighbour)#继续排队
		print(node)

(2) 找到最短路径(假设全部路径长度一样)

graph = {'A':['B','C'],
         'B':['D','A'],
         'D':['B','C'],
         'C':['D','E','A'],
         'E':['D','C','F'],
         'F':['E']} 
#首先使用字典创建一个图

def BFS(graph,start,end):#函数以图和起点以及中点作为变量
	queue = [[start,[start]]]#起点首先排进队列,这里加入一个列表进行记录路径
	alreadyTraverse = {start}#年轻的鹰的记性好,不会走相同的地方
	
	while (len(queue)>0):#不断遍历直到队中没有元素
		node,path=queue.pop(0)#取出队中的一个元素,分别赋给节点和路径
		for neighbour in graph[node]:#对于选中元素的所有邻居进行遍历
			if neighbour not in alreadyTraverse:#集合在python中是hashing判断速度快
				alreadyTraverse.add(neighbour)
				queue.append([neighbour,path+[neighbour]])#继续排队
				if neighbour == end:
					return path+[neighbour]

(3)找到全部路径

graph = {'A':['B','C'],
         'B':['D','A'],
         'D':['B','C'],
         'C':['D','E','A'],
         'E':['D','C','F'],
         'F':['E']} 
         
def BFS(graph,start,end):#函数以图和起点以及中点作为变量
	queue = [[start,[start]]]#起点首先排进队列,这里加入一个列表进行记录路径
	alreadyTraverse = {start}#年轻的鹰的记性好,不会走相同的地方
	allPath=[]#这个列表进行记录
	
	while (len(queue)>0):#不断遍历直到队中没有元素
		node,path=queue.pop(0)#取出队中的一个元素,分别赋给节点和路径
		for neighbour in graph[node]:#对于选中元素的所有邻居进行遍历
			if neighbour not in alreadyTraverse:#集合在python中是hashing判断速度快
				alreadyTraverse.add(neighbour)
				queue.append([neighbour,path+[neighbour]])#继续排队
				if neighbour == end:
					allPath.append(path+[neighbour])#找到之后不停止
	return allPath

(4)找路径(方法二)
除了使用以上方法还可以建立一棵树进行倒序查找,从目标节点不断地寻找父节点。

graph = {'A':['B','C'],
         'B':['D','A'],
         'D':['B','C'],
         'C':['D','E','A'],
         'E':['D','C','F'],
         'F':['E']} 
#首先使用字典创建一个图

def BFS(graph,start):#函数以图和起点作为变量
	queue = [start]#起点首先排进队列
	alreadyTraverse = {start}#年轻的鹰的记性好,不会走相同的地方
	parent={}#记录每一个节点的父节点
	while (len(queue)>0):#不断遍历直到队中没有元素
		node=queue.pop(0)#取出队中的一个元素
		for neighbour in graph[node]:#对于选中元素的所有邻居进行遍历
			if neighbour not in alreadyTraverse:#集合在python中是hashing判断快
				parent[neighbour]=node
				alreadyTraverse.add(neighbour)
				queue.append(neighbour)#继续排队
	return parent
	
def allPath(parent,start,end):
    path=[]
    while (start != end) :#使用while循环不断地找到end前面的元素
        path.append(end)
        end = parent[end]
        print(path)
    path+=[start]
    path.reverse()#由于是倒序查找所以需要倒序排列
    return path
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值