Dijkstra演算法(鄰接矩陣儲存)

來源:互聯網
上載者:User

標籤:style   blog   color   io   for   代碼   div   演算法   

首先我們需要熟悉Dijkstra演算法的原理:

從某個源點到其餘各頂點的最短路徑,即單源點最短路徑。單源點最短路徑是指:給定帶權有向圖G和源點v,求從v到G中其餘各頂點的最短路徑。迪傑斯特拉(Dijkstra)提出了按路徑長度遞增的順序產生各頂點的最短路徑演算法。 

該演算法的基本思想是: 

(1)設定兩個頂點的集合S和T=V-S,集合S中存放已找到最短路徑的頂點,集合T存放當前還未找到最短路徑的頂點; 

(2)初始狀態時,集合S中只包含源點v0; 

(3)從集合T中選取到某個頂點vi(要求vi到v0的路徑長度最小)加入到S中; 

(4)S中每加入一個頂點vi,都要修改頂點v0到T中剩餘頂點的最短路徑長度值,它們的值為原來值與新值的較小者,新值是vi的最短路徑長度加上vi到該頂點的路徑長度; 

(5)不斷重複(3)和(4),直到S包含全部頂點。

演算法的代碼實現很巧妙:

1.首先函數裡面運用數組D[n]表示源點到節點n的最短距離,s[n]表示某一節點n是否已經進入集合S,如果進入則將s[i]置為1.P[n]表示當前節點n的前驅節點(用來輸出路徑)。

2.在開始遍曆之前,首先給數組D[n]賦值為源點到該點的距離,這樣便能第一次找到源點到相鄰節點的最短距離(D[i]=C[v1][i];)。

3.下面找出最短距離:

if((!S[j])&&(D[j]<min))
{
min=D[j];
k=j;
}

4.更新各節點的最短距離:

for(j=0;j<n;j++)
{
if((!S[j])&&(D[j]>D[k]+C[k][j]))//調整各節點(未進入集合S)的距離值
{
D[j]=D[k]+C[k][j]; //修改藍點j+1的距離
P[j]=k+1; //k+1是j+1的前趨
}
}

4.代碼實現:

  1 #include<stdio.h>  2 #define maxsize 1000  //表示兩點間不可達,距離為無窮遠  3 #define n 7  //結點的數目  4 void dijkstra(int C[][n],int v);//求原點v到其餘頂點的最短路徑及其長度  5 void main()  6 {  7     8   //對鄰接矩陣進行賦值,沒有直接連通的賦值為maxsize  9   int C[n][n]= 10   { 11      {maxsize,13,8,maxsize,30,maxsize,32}, 12      {maxsize,maxsize,maxsize,maxsize,maxsize,9,7}, 13      {maxsize,maxsize,maxsize,5,maxsize,maxsize,maxsize}, 14      {maxsize,maxsize,maxsize,maxsize,6,maxsize,maxsize}, 15      {maxsize,maxsize,maxsize,maxsize,maxsize,2,maxsize}, 16      {maxsize,maxsize,maxsize,maxsize,maxsize,maxsize,17}, 17      {maxsize,maxsize,maxsize,maxsize,maxsize,maxsize,maxsize} 18   },v=1,i,j; 19   20  dijkstra(C,v);//迪傑斯特拉演算法 21   22 } 23 void dijkstra(int C[][n],int v)//求原點v到其餘頂點的最短路徑及其長度 24 { 25   26   27  int D[n];//用來儲存從起點到某一節點的最短距離 28  int P[n],S[n];//p[n]表示某一節點的父親,s[n]相當於標誌數組 29  int i,j,k,v1,pre; 30  int min,max=maxsize,inf=1200; 31  v1=v-1;//節點號和儲存的數目差1 32   33   34   35  for(i=0;i<n;i++) 36  { 37   D[i]=C[v1][i];   //置初始距離值 38   if(D[i]!=max) //說明存在邊 39    P[i]=v;//把父親置為v 40   else 41    P[i]=0;//否則父親置為0 42  } 43   44   45   46  for(i=0;i<n;i++) 47   S[i]=0;      //如果某點i被訪問則把該點值置為1,否則為0 48    49    50    51  S[v1]=1;//已經被訪問置為1 52  D[v1]=0;    //源點v送S 53   54   55   56  for(i=0;i<n-1;i++)   //擴充紅點集 57  { 58    59    60     min=inf;//令inf>max,保證距離值為max的藍點能擴充到S中 61     for(j=0;j<n;j++)//在當前藍點中選距離值最小的點k+1 62     { 63       if((!S[j])&&(D[j]<min)) 64       { 65         min=D[j];//找從起點開始的最小權值 66         k=j; 67       } 68     } 69      70    71    S[k]=1;    //已經被訪問,置為1 72    73    74   for(j=0;j<n;j++) 75   { 76     if((!S[j])&&(D[j]>D[k]+C[k][j]))//調整各藍點的距離值 77     { 78        D[j]=D[k]+C[k][j];  //修改藍點j+1的距離 79        P[j]=k+1;     //k+1是j+1的前趨 80     } 81   } 82    83    84  }  //所有頂點均已擴充到S中 85   86   87  for(i=0;i<n;i++)//輸出結果和最短路徑 88  { 89   printf("%d到%d的最短距離為",v,i+1); 90   printf("%d\n",D[i]);  //列印結果 91   pre=P[i]; 92   printf("路徑:%d",i+1); 93   while(pre!=0)  //繼續找前趨頂點 94   { 95    printf("<——%d",pre); 96    pre=P[pre-1]; 97   } 98   printf("\n"); 99  }100  101  102 }  

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.