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;
}