数据结构之广度优先算法的Python简单实现
2018-02-24 23:14
561 查看
问题描述,假设你经营着一家农场,需要寻找芒果销售商,以便将芒果卖给他。为此,我们的原则是先在一级朋友中查找,然后在二级朋友(朋友的朋友)、三级朋友(朋友的朋友的朋友)中查找。使用这种算法将搜遍你的人际关系网,直到找到芒果销售商,这就是广度优先搜索算法。
实现代码
这时出现了一种情况,Peggy既是Alice的朋友,又是Bob的朋友,因此她被加入队列两次。我们做了无用功。
此外,更严重的情况是,可能会导致无限循环。
解决方法就是使用一个列表来记录检查过的人,检查一个人之前,要确认他没有被检查过。考虑到这一点之后,更新代码如下
如果你在你的整个人际关系网中搜索芒果销售商,就意味着你将沿每条边前行(边是一个人到另一个人的箭头或者是连接),因此运行时间至少是O(边数)。
你还使用了一个队列,其中包含要检查的每个人。将每一个人添加到队列需要的时间是固定的,即为O(1),因此对每个人都这样做需要的总时间是O(人数)。
因此,广度优先搜索的运行时间是O(人数+边数),这通常写作O(V+E),其中V为顶点数,E为边数。
实现代码
from collections import deque graph = {} graph["you"] = ["alice","bob","claire"] graph["bob"] = ["anuj","peggy"] graph["alice"] = ["peggy"] graph["claire"] = ["thom","jonny"] graph["anuj"] = [] graph["peggy"] = [] graph["thom"] = [] graph["jonny"] = [] # 假设我们这样判断,如果这个人的姓名是以m结尾,那么它就是芒果销售商 def person_is_seller(name): return name[-1] == "m" def main(): # 创建一个队列 search_queue = deque() # 将你的邻居加入到这个搜索队列当中 search_queue += graph["you"] # 只要队列不为空,就取出其中的第一个人 while search_queue: person = search_queue.popleft() if person_is_seller(person): print(person + " is a mango seller!") return True else: search_queue += graph[person] return False if __name__ == '__main__': main()
这时出现了一种情况,Peggy既是Alice的朋友,又是Bob的朋友,因此她被加入队列两次。我们做了无用功。
此外,更严重的情况是,可能会导致无限循环。
解决方法就是使用一个列表来记录检查过的人,检查一个人之前,要确认他没有被检查过。考虑到这一点之后,更新代码如下
from collections import deque graph = {} graph["you"] = ["alice","bob","claire"] graph["bob"] = ["anuj","peggy"] graph["alice"] = ["peggy"] graph["claire"] = ["thom","jonny"] graph["anuj"] = [] graph["peggy"] = [] graph["thom"] = [] graph["jonny"] = [] # 假设我们这样判断,如果这个人的姓名是以m结尾,那么它就是芒果销售商 def person_is_seller(name): return name[-1< c529 /span>] == "m" def main(): # 创建一个队列 search_queue = deque() # 将你的邻居加入到这个搜索队列当中 search_queue += graph["you"] # 这个数据用于记录检查过的人 searched = [] # 只要队列不为空,就取出其中的第一个人 while search_queue: person = search_queue.popleft() # 仅当这个人没检查过的时候才检查 if not person 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 if __name__ == '__main__': main()
如果你在你的整个人际关系网中搜索芒果销售商,就意味着你将沿每条边前行(边是一个人到另一个人的箭头或者是连接),因此运行时间至少是O(边数)。
你还使用了一个队列,其中包含要检查的每个人。将每一个人添加到队列需要的时间是固定的,即为O(1),因此对每个人都这样做需要的总时间是O(人数)。
因此,广度优先搜索的运行时间是O(人数+边数),这通常写作O(V+E),其中V为顶点数,E为边数。
相关文章推荐
- python实现数据结构图-广度深度遍历
- Python实现简单时间人流数据收集工具
- 数据结构与算法——基数排序简单Java实现
- python 数据结构之双向链表的实现
- Python实现常用的逻辑数据结构
- Json树形结构数据转Java对象并存储到数据库的实现-超简单的JSON复杂数据处理 .
- 简单数据结构实现——二叉查找树
- 数据结构(java语言描述)-- 栈的两种简单实现
- 算法与数据结构基础3:C++单链表类的简单实现
- Python -- 数据结构实现
- 算法与数据结构基础7:C++双链表的简单实现
- 数据结构书中基于整数的简单排序Java实现,巩固一下基础
- 算法与数据结构基础5:C++栈的简单实现
- 简单数据结构实现——双链表
- 简单数据结构实现——队列
- 简单数据结构实现——堆栈
- 数据结构7:队列的简单实现
- 数据结构 学习笔记之:静态链表--史上最简单的C语言实现——只为掌握概念——不清楚静态链表的鸟鸟们有福了!
- C++和python利用struct结构传输二进制数据实现
- 数据结构作业 ------ 用链表实现简单多项式加法