首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

經典算法研究:Dijkstra算法原理、實現與複雜度分析

     編輯:關於C語言

Dijkstra算法是單源最短路徑問題的經典解法,適用於非負權圖。本文系統梳理算法邏輯、三種優先隊列實現的複雜度對比、圖文演示步驟,並關聯Prim、BFS等同類算法。

一、 問題定義與貪心策略

給定有向圖G=(V,E)、權重函數w: E→[0,∞)、源點s。求s到所有頂點的最短路徑。
核心思想:貪心—— 每次從未確定集合中選取距離源點最近的頂點u,宣告其最短路徑已確定,並以此「鬆弛」出邊。

二、 標準偽代碼(算法導論版)


DIJKSTRA(G, w, s)
1  INITIALIZE-SINGLE-SOURCE(G, s)  // d[v]=∞, π[v]=NIL, d[s]=0
2  S ← ∅
3  Q ← V[G]                         // 優先隊列,鍵值為 d[v]
4  while Q ≠ ∅
5      u ← EXTRACT-MIN(Q)           // 取距離最小頂點
6      S ← S ∪ {u}
7      for each v ∈ Adj[u]          // 鬆弛出邊
8          do RELAX(u, v, w)

鬆弛操作


RELAX(u, v, w)
if d[v] > d[u] + w(u,v)
    d[v] ← d[u] + w(u,v)
    π[v] ← u

三、 複雜度取決於優先隊列實現

實現方式EXTRACT-MINDECREASE-KEY總時間適用場景
數組/鏈表O(V)O(1)O(V²+E)稠密圖、教學演示
二叉堆O(log V)O(log V)O((V+E)log V) ≈ O(E log V)稀疏圖、通用首選
斐波那契堆O(log V)O(1) 平攤O(V log V + E)理論最優、E ≫ V 時優勢明顯

稀疏圖E=O(V²/log V)時,二叉堆退化至O(V²);斐波那契堆始終保持O(V log V + E)。

四、 圖文演示:六節點無向圖

Dijkstra演示圖

源點 A,求到 B/C/D/E/F 最短路徑。算法以 A 為中心向外層層擴展,每輪鎖定一個頂點。

執行步驟表(節選)

輪次S (已確定)Q 中 d 值變化EXTRACT-MIN
0∅A:0, B:∞, C:∞, D:∞, E:∞, F:∞A (d=0)
1{A}C:3, B:6, D:∞, E:∞, F:∞C (d=3)
2{A,C}B:5, D:6, E:7, F:∞B (d=5)
3{A,C,B}D:6, E:7, F:9D (d=6)
4{A,C,B,D}E:7, F:9E (d=7)
5{A,C,B,D,E}F:9F (d=9)

最終最短路徑:A→C→B(5)、A→C(3)、A→C→D(6)、A→C→E(7)、A→C→D→F(9)。

五、 相關算法對比

  • Bellman-Ford:允許負權邊(無負權環),O(VE),可檢測負環。
  • A*:引入h(n)啟發,單對最短路徑更快。
  • OSPF:Dijkstra在網絡路由中的工程化實現。
  • Prim:最小生成樹,結構極似,同用貪心+優先隊列。

六、 複雜度總結表

算法時間複雜度備註
BFS/DFSO(V+E)無權圖
KruskalO(E log V)最小生成樹
Prim (斐波那契堆)O(E + V log V)稠密圖優勢大
Dijkstra (斐波那契堆)O(V log V + E)與Prim同級

掌握 Dijkstra 的鬆弛框架與優先隊列選型,即掌握了加權圖最短路徑的通用解法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved