算法学习之广度优先搜索

图和广度优先搜索的基本概念

图模拟一组连接,根据连接的线段有方向和无方向分为有向图无向图

图由节点和边组成。一个节点可能与众多节点直接相连,这样直接相连的节点称为邻居。

而广度优先搜索,简称BFS,是从根节点开始,沿着树的宽度(广度)遍历树的节点,如果发现目标,则演算终止。

所以,你需要建立一个人际关系图,其中有一度朋友关系,二度朋友关系等等,其中一度朋友关系大于二度朋友关系,依此类推。

当你冥思苦想加上打电话询问你的朋友都有哪些朋友之后,你终于建立好了这张人际关系图。

此时,你肯定是首先在所有一度朋友关系的人里面搜索,看看有没有卖房子的,如果有,OK直接找他了;如果没有,再去找二度朋友关系(朋友的朋友)的人;如果再没有再去找三度朋友关系的人;依此类推。

上面这种思路就是广度优先搜索!

广度优先搜索可解决的问题:

  • 从节点A出发,有前往节点B的路径吗?
  • 从节点A出发,前往B的哪条路径最短?

算法实现

要达到目的,只有添加顺序查找,才能达到目的。即,只有先添加你的朋友,把你的朋友查询完后,在添加你朋友的朋友,将你朋友的朋友查询完后,在添加朋友的朋友的朋友,以此类推。有一个可实现这种目的的数据结构,那就是队列。

  • 队列是一种先进先出(Fist In Fist Out)的数据结构,而栈是一种后进先出的数据结构。

你和你的朋友们的关系以及他们的朋友关系,可以用散列表来表示。散列表可以使键映射到值,在这里,要将节点映射到所有的朋友,例如:

graph = {}
graph["you"] = ["alice", "bob", "claire"]

“你”被映射到了一个数组,因此graph["you"]是一个数组,其中包含了“你”的所有朋友。

完整的朋友关系散列图代码:

graph = {}
graph["you"] = ["alice", "bob", "claire"]   #对应的值为一个数组
graph["bob"] = ["peggy", "anuj"]
graph["peggy"] = []
graph["anuj"] = []
graph["alice"] = ["peggy"]
graph["claire"] = ["thon", "jonnym"]
graph["thon"] = []
graph["jonny"] = []

要注意的是,添加关系时的前后顺序不影响结果,因为散列图时无序的,因此添加 键-值对的顺序无关紧要。

现在关系图已经建立好了,那么接下来就是实现找 卖房子的 人了。

from collections import deque
def person_is_seller(name):
    return name[-1] == "m"     #检查人的姓名是否以m结尾,有点草率0.0

def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []                 #这个数组用于记录检查过的人
    while search_queue:
        person = search_queue.popleft()
        if person not in searched:           #这个人没有检查时才检查
             if person_is_seller(person):
                 print (person)
                 return True
             else:
                  search_queue += graph[person]
                  searched.append(person)         #将这个人标记为已检查
    return False

第一个if语句的必要性。存在这样的一种情况,A的朋友时B,B的朋友是A。那么就会陷入无限循环。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值