數(shù)據(jù)結(jié)構(gòu)之圖的Dijkstra算法

Dijkstra算法

  1. 定義概覽
    Dijkstra(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計(jì)算一個(gè)節(jié)點(diǎn)到其他所有節(jié)點(diǎn)的最短路徑。主要特點(diǎn)是以起始點(diǎn)為中心向外層層擴(kuò)展,直到擴(kuò)展到終點(diǎn)為止。Dijkstra算法是很有代表性的最短路徑算法,在很多專業(yè)課程中都作為基本內(nèi)容有詳細(xì)的介紹,如數(shù)據(jù)結(jié)構(gòu),圖論,運(yùn)籌學(xué)等等。注意該算法要求圖中不存在負(fù)權(quán)邊。
    問題描述:在無向圖 G=(V,E) 中,假設(shè)每條邊 E[i] 的長度為 w[i],找到由頂點(diǎn) V0 到其余各點(diǎn)的最短路徑。(單源最短路徑)

  2. 算法描述

  1. 算法思想:設(shè)G=(V,E)是一個(gè)帶權(quán)有向圖,把圖中頂點(diǎn)集合V分成兩組,第一組為已求出最短路徑的頂點(diǎn)集合(用S表示,初始時(shí)S中只有一個(gè)源點(diǎn),以后每求得一條最短路徑 , 就將加入到集合S中,直到全部頂點(diǎn)都加入到S中,算法就結(jié)束了),第二組為其余未確定最短路徑的頂點(diǎn)集合(用U表示),按最短路徑長度的遞增次序依次把第二組的頂點(diǎn)加入S中。在加入的過程中,總保持從源點(diǎn)v到S中各頂點(diǎn)的最短路徑長度不大于從源點(diǎn)v到U中任何頂點(diǎn)的最短路徑長度。此外,每個(gè)頂點(diǎn)對應(yīng)一個(gè)距離,S中的頂點(diǎn)的距離就是從v到此頂點(diǎn)的最短路徑長度,U中的頂點(diǎn)的距離,是從v到此頂點(diǎn)只包括S中的頂點(diǎn)為中間頂點(diǎn)的當(dāng)前最短路徑長度。
  2. 算法步驟:
    a.初始時(shí),S只包含源點(diǎn),即S={v},v的距離為0。U包含除v外的其他頂點(diǎn),即:U={其余頂點(diǎn)},若v與U中頂點(diǎn)u有邊,則<u,v>正常有權(quán)值,若u不是v的出邊鄰接點(diǎn),則<u,v>權(quán)值為∞。
    b.從U中選取一個(gè)距離v最小的頂點(diǎn)k,把k,加入S中(該選定的距離就是v到k的最短路徑長度)。
    c.以k為新考慮的中間點(diǎn),修改U中各頂點(diǎn)的距離;若從源點(diǎn)v到頂點(diǎn)u的距離(經(jīng)過頂點(diǎn)k)比原來距離(不經(jīng)過頂點(diǎn)k)短,則修改頂點(diǎn)u的距離值,修改后的距離值的頂點(diǎn)k的距離加上邊上的權(quán)。
    d.重復(fù)步驟b和c直到所有頂點(diǎn)都包含在S中。
/***  遞歸
**graph:存儲圖信息的內(nèi)存地址,圖已排好序
**dist:圖中每個(gè)點(diǎn)到S點(diǎn)的距離,初始都為0
**v[]:圖中每個(gè)點(diǎn)是否訪問過的標(biāo)志
**vn:當(dāng)前訪問的節(jié)點(diǎn)ID
**uNum:圖中剩余沒訪問點(diǎn)數(shù),為0則程序結(jié)束。
***/
void dijkstra(graph_t *graph, int dist[], int v[],  int vn, int uNum)
 {
      if(uNum <= 0){
          return;
      }
      printf("%d--%d\n",vn, uNum);
      int flag = 1, vt = 0;
      gnode_t *p = graph->relation[vn].next; /* 與VN相連接的點(diǎn) */
 
      if(p == NULL){
          return ;
      }
      v[vn] = 1;
 
      while(p != NULL){ /* 訪問所有與VN相連接的點(diǎn) */
          if(flag && !v[p->data]){  /* 與vn相連的未被訪問過的最近(越靠前越近)的點(diǎn),用作往下遞歸的起點(diǎn) */
                  vt = p->data;
                  flag = 0;
          }
          if(0 == dist[p->data] || dist[p->data] > dist[vn] + p->weight){ /* 無向圖,p->weight為權(quán)重 */
              dist[p->data] = dist[vn] + p->weight;
          }
          printf("     %d -- %d\n",p->data, dist[p->data]);
          p = p->next;
      }
 
      dijkstra(graph, dist, v, vt, --uNum);
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • https://zh.visualgo.net/graphds 淺談圖形結(jié)構(gòu)https://zh.visualgo...
    狼之獨(dú)步閱讀 4,427評論 0 0
  • 1736年,瑞士數(shù)學(xué)家Euler(歐拉)在他的一篇論文中討論了格尼斯七橋問題,由此誕生了一個(gè)全新的數(shù)學(xué)分支——圖論...
    不困于情閱讀 4,535評論 0 9
  • -DFS(Depth First Search):深度優(yōu)先搜索 訪問完一個(gè)頂點(diǎn)的所有鄰接點(diǎn)之后,會按原路返回,對應(yīng)...
    Spicy_Crayfish閱讀 2,953評論 1 0
  • 魚爸:魚大大你剛吃好飯又吃餅干,胖死你,(瞄一眼)喲,這什么口味的,夾心啊,給我吃兩塊! 魚大大:你剛吃好飯又要吃...
    我有第三只眼閱讀 297評論 0 0
  • 最近迷上玩創(chuàng)客直播啦. 在里面我加了到女粉絲男粉絲!首先我不是為賣產(chǎn)品而賣產(chǎn)品.都是以交朋友為目的! 有時(shí)候不去嘗...
    閆小麗閱讀 281評論 0 0

友情鏈接更多精彩內(nèi)容