最短路径笔记(二):Dijkstra

注意点:

1,每次必须get离原点最近的点才可以

因为离原点较远的点一定在离原点较近的点的后面,

这样遍历较远的点的时候能确保它之前的点已经更新过最短路径

2,由于每次需要get最近的元素,所以可以用二叉堆实现优先队列,使得最小成员始终排在队首,获取最小成员时间复杂度降为O(logN)

3,使用邻接表代替邻接矩阵有两种方法,一种用链表的,一种用数组

数组可以分别创建五个数组,起点,终点,权值,前驱,后继来存储值,数组的每个索引的对应的所有数据代表一条数据

adj=[[0,1,12,-1,-1,-1],
     [-1,0,9,3,-1,-1],
     [-1,-1,0,-1,5,-1],
     [-1,-1,4,0,13,15],
     [-1,-1,-1,-1,0,4],
     [-1,-1,-1,-1,-1,0]]
 
 
#最短路径列表dis
dis=[0,-1,-1,-1,-1,-1]
to_get_min_path=[0,1,2,3,4,5]
has_get_min_path=[]
 
#直接按顺序遍历待遍历路径得到的结果是错误的
#每次需要遍历下一个离原点最近的元素
#原因后面的是离远点更远元素需要用到前面的离原点更近的元素的最短路径,感觉还是有些不清晰,需要有时间再看
def get_nearest_elem(p):
    count=0
    while p:
        minx=float("inf")
        min_e=None
        for e in p:
            count+=1
            if dis[e]<minx:
                minx=dis[e]
                min_e=e
                print(min_e)
        has_get_min_path.append(min_e)
        yield p.pop(p.index(min_e))
 
for t in range(6):
    if dis[t]==-1:
        dis[t]=float("inf")
 
for x in get_nearest_elem(to_get_min_path):
    print(x)
    for y in range(6):
        #判断是否相连
        if adj[x][y]!=0 and adj[x][y]!=-1:
            #注意:最短路径指从起点到当前节点的路径,下方是Dijkstra的核心
            #判断如果当前节点的最短路径 大于 相连的节点的最短路径+相连节点到当前节点的路径长度
            if dis[y]>dis[x]+adj[x][y]:
                dis[y]=dis[x]+adj[x][y]   
print(dis)
可以直接留言交流问题或想法,每天都会看
原文地址:https://www.cnblogs.com/shitianfang/p/12411615.html