《算法图解》第六章广度优先搜索学习心得

1、图简介

最短路径问题(shorterst-path problem),如前往朋友家的最短路径, 也可能是国际象棋中把对方将死的最少步数。 解决

最短路径问题的算法被称为广度优先搜索 。 解决最短路径问题需要两个步骤:

  • 使用图来创建问题模型。
  • 使用广度优先搜索解决问题。

图仿真一组连接。 图由节点 (node) 和边 (edge)组成。一个节点可能与众多节点直接相连,这些节点被称为邻居 。

有向图 (directedgraph)的关系是单向的。无向图 (undirected graph) 没有箭头, 直接相连的节点互为邻居。


2、广度优先搜索

广度优先搜索解决两类问题:

  • 第一类问题: 从节点A出发, 有前往节点B的路径吗?
  • 第二类问题: 从节点A出发, 前往节点B的哪条路径最短?
广度优先搜索不仅查找从AB的路径, 而且找到的是最短的路径。
3、队列(queue
队列只支持两种操作: 入队和出队 。队列类似于栈, 你不能随机地访问队列中的元素。队列是一种先进先出 (First In First OutFIFO) 的数据结构, 而栈是一 种后进先出 (Last In First OutLIFO) 的数据结构。 如下图


4、算法实现

实现下图,需要用到散列表(python中为字典)


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"] = []

你的人际关系网中搜索芒果销售商的算法:

def search(name):
    #使用函数deque 来创建一个双端队列
    from collections import deque
    search_queue=deque()#创建一个队列
    search_queue += graph["you"]#将你的邻居都加入到这个搜索队列中
    searched=[]
    while search_queue:#只要队列不为空
        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#如果到达了这里, 就说明队列中没人是芒果销售商
#判断一个人是不是芒果销售商
def person_is_seller(name):
    '''这个函数检查人的姓名是否以m结尾: 如果是, 他就是芒果销售商。 这种判断方法有点搞笑, 但就这个示例而言是可行的。
    '''
    return name[-1]=="m"

5、运行时间

广度优先搜索的运行时间为O (人数 + 边数), 这通常写作O (V + E ), 其中V 为顶点(vertice) 数, E 为边数。

6、拓扑排序

如果任务A依赖于任务B, 在列表中任务A就必须在任务B后面。 这被称为拓扑排序 , 使用它可根据图创建一个有序列表。 

7、小结

  • 广度优先搜索指出是否有从AB的路径。
  • 如果有, 广度优先搜索将找出最短路径。
  • 面临类似于寻找最短路径的问题时, 可尝试使用图来创建模型, 再使用广度优先搜索来解决问题。
  • 有向图中的边为箭头, 箭头的方向指定了关系的方向, 例如,rama→adit表示ramaadit钱。
  • 无向图中的边不带箭头, 其中的关系是双向的, 例如, ross - rachel表示“rossrachel约会, 而rachel也与ross约会
  • 队列是先进先出FIFO) 的。
  • 栈是后进先出LIFO) 的。
  • 你需要按加入顺序检查搜索列表中的人, 否则找到的就不是最短路径, 因此搜索列表必须是队列
  • 对于检查过的人, 务必不要再去检查, 否则可能导致无限循环。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值