相比较贝尔曼-福特算法须要每次对全部边进行松弛操做,时间复杂度为O(顶点数*边数),而且能够处理负权边,可是咱们在实际生活中,计算路径的时候,极少遇到负权边的状况,因此只考虑正权边的状况下,能够采用更优化的Dijkstra算法。算法
Dijkstra算法设置了两个集合,设全部顶点集合为V,则:数组
S=全部与起点s已经肯定最短路径、最低权重值的顶点。ide
W=V-S。优化
算法每次都将W中权重值最小的顶点u移入S中,并对u的全部边进行松弛操做。3d
看图说话:code
初始化:blog
S=A0 W=B∞,C∞,D∞,E∞,F∞,G∞
一、须要对A的全部边进行松弛操做,结果排序
S=A0 W=B6,C4,D∞,E∞,F∞,G∞
二、取出W中最小的顶点C放入S,并对C全部边进行松弛操做,结果队列
S=A0,C4 W=B6,D9,E∞,F11,G∞
三、取出W中最小顶点B放入S,并对B全部边进行松弛操做,结果it
S=A0,B6,C4 W=D9,E11,F11,G∞
四、取出W中最小的顶点D放入S,并对D全部边进行松弛操做,结果
S=A0,B6,C4,D9 W=E11,F10,G∞
五、取出W中最小的顶点F放入S,并对F全部边进行松弛操做,结果
S=A0,B6,C4,D9,F10 W=E11,G∞
六、取出W中最小的顶点E放入S,并对E全部边进行松弛操做,结果
S=A0,B6,C4,D9,E11,F10 W=G∞
七、取出W中最小的顶点G放入S,并对G全部边进行松弛操做,结果
S=A0,B6,C4,D9,E11,F10,G∞
至此,咱们能够得出一个最短路径树:
A——B=6 A——C=4 A——C——D=9 A——B——E=11 A——C——D——F=10 A没法到达G
在这里有两个地方能够优化:
一、由于要取出权重最小的顶点,因此每次都要对W进行排序,采用遍历数组进行比较的算法,不如采用优先队列(PriorityQueue),由于优先队列采用了堆结构,排序时间复杂度是O (nlgn)。
二、若是咱们只是想计算起点到某点的最短距离,那么在遍历的时候,检查一下取出的最小顶点是不是终点,若是是,跳出循环便可。