相比較貝爾曼-福特算法須要每次對全部邊進行鬆弛操做,時間複雜度爲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)。
二、若是咱們只是想計算起點到某點的最短距離,那麼在遍歷的時候,檢查一下取出的最小頂點是不是終點,若是是,跳出循環便可。