欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(原创)广度优先搜索解决最短路径问题

程序员文章站 2022-06-11 21:01:56
...

一、用途

广度优先搜索用于解决两种问题:
1.从某点到某点是否存在路径?
2.若存在,最短的是哪条?


二、简单介绍图

1.图有点和边组成
2.当图中的所有边的指向都是单向的,这种图叫做有向图。若A指向B,则B为A的邻居
3.当图中存在一条或一条以上的没有箭头的边,即A指向B,且B指向A,这种图成为无向图。其中,A和B互为邻居
4.如下图,其中若从A出发,则B、C、D是一度关系,E、F是二度关系,以此类推。

(原创)广度优先搜索解决最短路径问题


三、简单介绍队列

1.队列只包括两种操作:入队与出队
2.队列是一种先进先出的数据结构(First In First Out,FIFO);栈是一种后进先出的数据结构(Last In First Out,LIFO)。


四、广度优先算法实现逻辑

假设要在上图中寻找从A到E的最短路径:
1.将A的一度关系加入搜索队列。
2.判断搜索队列是否为空,是则返回False,表示不存在到E的路径,否则检查队列的第一个点。
2.检查该点是否被搜索过了,是则跳过。否则判断该点是否是E,是则返回true,否则将该点移除,并放入已经搜索过的点的列表,将该点的下一层加入整个待搜索队列的后面。
3.重复第二步。

注意!!
a.要将下一层放在队列的最后面,才能确保找到的是最短路径。
b.检查过的点要放入已经搜索过的队列,并在每次检查时判断该点是否在搜索过的队列里,防止重复搜索。否则当出现无向图时,会进入死循环。

五、运行时间

广度优先搜索的运行时间是:O(V+E)
解析:
广度优先遍历需要在整个图网中进行遍历,所以会遍历每一条边,所以至少运行时间是O(边数),即O(E),E为边数;
而每次遍历一个点,就需要将它的下一层添加到队列,在散列表中添加一个对象是常数时间O(1),所以运行时间还要加上O(节点数),即O(V),V是节点数。
所以最后的运行时间是:O(V) + O(E) = O(V+E)。

六、具体实现

"""
广度优先搜索
"""
dict = {}
dict["oysq"] = ["a", "b", "c"]
dict["a"] = ["e", "f", "g"]
dict["b"] = ["h", "i"]
dict["c"] = []
dict["d"] = []
dict["e"] = []
dict["f"] = []
dict["g"] = []
dict["h"] = ["j", "k"]
dict["i"] = []
dict["j"] = []
dict["k"] = ["l"]
dict["l"] = []

def search(dict, head, target):
    search_list = []
    search_list += dict[head]
    searched = []
    while search_list != []:
        temp = search_list.pop()
        if searched.count(temp) == 0:
            if temp == target:
                return True;
            else:
                search_list += dict[temp]
                searched += temp
    return False
    
print search(dict, "oysq", "c")
print search(dict, "oysq", "v")

欢迎大家评价交流!!