Dijkstra最短路徑算法

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.以該節點爲當前工做點。再對照該點的鄰接矩陣的信息,若是VA再到Ui】的路徑值小於Ui】當前記錄的路徑值,那麼就改變Ui】的路徑值,以後再改變Ui】的前趨信息,即下面的U[i].from。對Ui】所有訪問完後,對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;

}


上面的判斷就是利用了回溯的思想。Uk】是已經肯定訪問過的點,因此Uk.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;

}

相關文章
相關標籤/搜索