广度优先搜索
广度优先搜索算法(英语:Breadth-First Search,缩写BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索方法。简单的说,BFS是从根节点开始,沿着树德宽度遍历树德节点。如果所有节点均被访问,则算法终止。广度优先搜索的实现一般采用open-closed表。
BFS是一种盲目搜索法,目的是系统的展开并检查图中的所有节点,以寻找结果。换句话说,它并不考虑结果的可能地址,彻底的搜索整张图,直到找到结果为止。
从算法的观点,所有因为展开节点而得到的子节点都会被加入一个先进先出的队列中。一般在实现过程中,其邻居节点尚未被检验过的节点会被放置在一个被称为open的容器中(例如队列或者链表),而被检验过的节点则被放置在被称为closed的容器中。(open-closed表)
广度优先搜索(BFS),实现的方法:
1. 首先将根节点放入队列中;
2. 从队列中取出第一个节点,并检验它是否为目标:
·如果找到目标,结束搜索并回传结果;
·否则将它所有尚未检验过的直接子节点加入队列中。
3. 若队列为空,表示整张图都检查过了--也就代表图中没有要搜索的目标。结束搜索并回传“找不到目标”;
4. 重复步骤2。
广度优先搜索--时间复杂度
因为所有节点都必须被存储,最差情况下,BFS必须查找所有可能节点的路径,因此BFS的时间复杂度为O(|V|+|E|),其中|V|是节点的数目,而|E|是图中边的数目。由于对空间的大量需求,因此BFS并不适合解决非常大的问题。
from collections import deque
graph = {} #创建一个名为graph的散列表
graph["you"] = ["alice","bob","claire"] #graph["you"]是一个数组,其中包含了“you”的所有邻居
graph["alice"] = ["peggy"]
graph["bob"] = ["anuj","peggy"]
graph["claire"] = ["thom","jonny"]
graph["peggy"] = []
graph["anuj"] = []
graph["thom"] = []
graph["jonny"] = []
def person_is_seller(name): #判断一个人是不是芒果销售商的函数
return name[-1] == 'm' #这个函数检查人的姓名是不是以m结尾:如果是,他就是芒果销售商。
def search(name):
search_queue = deque() #创建一个队列
search_queue += graph["you"] #将你的邻居都加入到这个搜索队列
searched = [] #这个数据用于记录检查过的人
while search_queue: #只要队列不为空就执行while循环
person = search_queue.popleft()
if person not in searched: #仅当这个人没有检查过时才检查
if person_is_seller(person): #检查这个人是否是芒果销售商
print(person + " is a mango seller!") #是芒果销售商
return True
else:
search_queue += graph[person] #不是芒果销售商。将这个人的朋友都加入搜索队列
searched.append(person) #将这个人标记为检查过
return False #如果到达了这里,就说明队列中没有人是芒果销售商
search("you")
图
图的定义:
图G定义为V和E的集合G={V, E},其中V表示图中的所有的顶点集合,E表示的是G中的所有的边的集合。图按照E中的元素是否有方向,分为有向图和无向图。
上面给出的数学上图的定义,那么在计算机中如何表示图?通常意义上,有下面的两种方法:邻接表和邻接矩阵表示法。
无向图的邻接表和邻接矩阵表示如下所示:
图模拟一组链接;
图由节点和边组成;一个节点可能与众多节点直接相连,这些节点被称为邻居;
图用于模拟不同的东西如何连接的;
广度优先搜索是一种用于图的查找算法,可帮助回答两类问题:
第一类问题:从节点A出发,有前往节点B的路径吗?
第二类问题:从节点A出发,前往节点B的哪条路径最短?
有向图(directed graph),有箭头,其中的关系是单向的;
无向图(undirected graph),没有箭头,直接相连的节点互为邻居。
树 是一种特殊的图。