相比較貝爾曼-福特算法需要每次對所有邊進行松弛操作,時間複雜度為o(頂點數*邊數),并且可以處理負權邊,但是我們在實際生活中,計算路徑的時候,極少遇到負權邊的情況,是以隻考慮正權邊的情況下,可以采用更優化的dijkstra算法。
dijkstra算法設定了兩個集合,設所有頂點集合為v,則:
s=所有與起點s已經确定最短路徑、最低權重值的頂點。
w=v-s。
算法每次都将w中權重值最小的頂點u移入s中,并對u的所有邊進行松弛操作。
看圖說話:
初始化:
1、需要對a的所有邊進行松弛操作,結果
2、取出w中最小的頂點c放入s,并對c所有邊進行松弛操作,結果
3、取出w中最小頂點b放入s,并對b所有邊進行松弛操作,結果
4、取出w中最小的頂點d放入s,并對d所有邊進行松弛操作,結果
5、取出w中最小的頂點f放入s,并對f所有邊進行松弛操作,結果
6、取出w中最小的頂點e放入s,并對e所有邊進行松弛操作,結果
7、取出w中最小的頂點g放入s,并對g所有邊進行松弛操作,結果
s=a0,b6,c4,d9,e11,f10,g∞
至此,我們可以得出一個最短路徑樹:
在這裡有兩個地方可以優化:
1、因為要取出權重最小的頂點,是以每次都要對w進行排序,采用周遊數組進行比較的算法,不如采用優先隊列(priorityqueue),因為優先隊列采用了堆結構,排序時間複雜度是o (nlgn)。
2、如果我們隻是想計算起點到某點的最短距離,那麼在周遊的時候,檢查一下取出的最小頂點是否是終點,如果是,跳出循環即可。