一.最短路徑的最優子結構性質java
該性質描述爲:若是P(i,j)={Vi....Vk..Vs...Vj}是從頂點i到j的最短路徑,k和s是這條路徑上的一箇中間頂點,那麼P(k,s)一定是從k到s的最短路徑。下面證實該性質的正確性。web
假設P(i,j)={Vi....Vk..Vs...Vj}是從頂點i到j的最短路徑,則有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而P(k,s)不是從k到s的最短距離,那麼一定存在另外一條從k到s的最短路徑P'(k,s),那麼P'(i,j)=P(i,k)+P'(k,s)+P(s,j)<P(i,j)。則與P(i,j)是從i到j的最短路徑相矛盾。所以該性質得證。算法
二. Dijkstra算法spa
Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其餘全部節點的最短路徑。主要特色是以起始點爲中心向外層層擴展,直到擴展到終點爲止。Dijkstra算法能得出最短路徑的最優解,但因爲它遍歷計算的節點不少,因此效率低。code
先給出一個無向圖orm
用Dijkstra算法找出以A爲起點的單源最短路徑步驟以下路由
三. 代碼get
Javait
static int[] testDijkstra(int n,int v,int[] dist,int[] prev,int[][] c){ int maxnum = 100; int maxint = 999999; boolean[] s = new boolean[maxnum]; // 判斷是否已存入該點到S集合中 for(int i=1; i<=n; ++i) { dist[i] = c[v][i]; s[i] = false; // 初始都未用過該點 if(dist[i] == maxint) prev[i] = 0; else prev[i] = v; } dist[v] = 0; s[v] = true; // 依次將未放入S集合的結點中,取dist[]最小值的結點,放入結合S中 // 一旦S包含了全部V中頂點,dist就記錄了從源點到全部其餘頂點之間的最短路徑長度 // 注意是從第二個節點開始,第一個爲源點 for(int i=2; i<=n; ++i) { int tmp = maxint; int u = v; // 找出當前未使用的點j的dist[j]最小值 for(int j=1; j<=n; ++j) if((!s[j]) && dist[j]<tmp) { u = j; // u保存當前鄰接點中距離最小的點的號碼 tmp = dist[j]; } s[u] = true; // 表示u點已存入S集合中 // 更新dist for(int j=1; j<=n; ++j) if((!s[j]) && c[u][j]<maxint) { int newdist = dist[u] + c[u][j]; if(newdist < dist[j]) { dist[j] = newdist; prev[j] = u; } } } return dist; }