Dijkstra最短路徑算法ios
思路:算法
首先對一個有向圖,我用鄰接矩陣進行存儲:spa
65536 3 4 65536 12 65536 ci
65536 65536 9 65536 5 65536 it
65536 65536 65536 6 65536 65536 io
65536 65536 65536 65536 65536 65536 stream
65536 65536 7 11 65536 20 im
65536 5 65536 65536 65536 65536 數據
圖:img
首先,創建一個鄰接矩陣這個確定是必須的。先說說Dijkstra算法的步驟。一個D圖,有n個節點,設起點爲V。
1.用U來存儲V的對應鄰接矩陣中的元素(一行),對U中的V進行訪問標記。
2.找到U中除了已經標記訪問外的,對應路徑值最小的節點A。
3.以該節點爲當前工做點。再對照該點的鄰接矩陣的信息,若是V到A再到U【i】的路徑值小於U【i】當前記錄的路徑值,那麼就改變U【i】的路徑值,以後再改變U【i】的前趨信息,即下面的U[i].from。對U【i】所有訪問完後,對A進行訪問標記。
4.重複2.3操做。直到所有的節點都已經被訪問。
其實上面若是對一個最小值進行了一次操做並標記訪問後,這點就已經肯定從開始節點到該點
的最短路徑了。這樣就符合回溯的思想,我根本不須要去管我訪問過的那些點了。由於他們已經肯定是最小。因此咱們在操做新節點的時候就能夠直接利用這些信息。
if( *(disk+k*n+j) + U[k].data < U[j].data ) {
U[j].data=*(disk+k*n+j) + U[k].data ;
U[j].from=k;
}
上面的判斷就是利用了回溯的思想。U【k】是已經肯定訪問過的點,因此U【k】.data記錄的必定是從開始節點到這個節點的最短路徑,因此修改新數據的時候就能夠直接使用它。
/*
*Dijkstra最短路徑算法--我的版
* */
#include<iostream>
#include<cstdio>
#define n 6
#define MAXDATA 65536
using namespace std;
typedef struct Links_ Links;
struct Links_ {
int data;
int visit;
int from;
};
int disk[n][n];
Links U[n];
void InitData(int *disk){
freopen("read1.txt","r",stdin);
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>*(disk+i*n+j);
}
void InitV(int v,Links *U,int *disk){
int i;
for(i=0;i<n;i++) {
U[i].data=*(disk+v*n+i);
U[i].visit=0;
U[i].from=v;
}
U[v].visit=1;
}
void GetData(Links *U,int *min,int *k){
int i,m=MAXDATA;
for(i=0;i<n;i++)
if(m>U[i].data && !U[i].visit ){
m=U[i].data;
*k=i;
}
*min=m;
}
void Dijkstra(int v,Links *U,int *disk){
int i=1,j,min,k,first=1;
int way;
InitV(v,U,disk);
while( i< n){
GetData(U,&min,&k);
for(j=0;j<n;j++)
if( *(disk+k*n+j) + U[k].data < U[j].data ) {
U[j].data=*(disk+k*n+j) + U[k].data ;
U[j].from=k;
}
U[k].visit=1;
i++;
}
}
int PrintU(int v,Links u,Links *U){
int i,j;
if(u.from == v) {
cout<<v<<"--";
return 0;
}
else {
PrintU(v,U[u.from],U);
cout<<u.from<<"--";
}
return 0;
}
void PrintLinks(int v,Links *U){
int i=0;
for(i=0;i<n;i++) {
PrintU(v,U[i],U);
cout<<i<<" :"<<U[i].data<<"\n";
}
}
int main(){
int v=0;
InitData(&disk[0][0]);
Dijkstra(v,U,&disk[0][0]);
PrintLinks(v,U);
return 0;
}