日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最短路径之迪杰斯特拉(Dijkstra 算法)弗洛伊德算法(C语言完整代码实现)

發布時間:2024/10/14 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短路径之迪杰斯特拉(Dijkstra 算法)弗洛伊德算法(C语言完整代码实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在前面:博主是一位普普通通的19屆雙非軟工在讀生,平時最大的愛好就是聽聽歌,逛逛B站。博主很喜歡的一句話花開堪折直須折,莫待無花空折枝:博主的理解是頭一次為人,就應該做自己想做的事,做自己不后悔的事,做自己以后不會留有遺憾的事,做自己覺得有意義的事,不浪費這大好的青春年華。博主寫博客目的是記錄所學到的知識并方便自己復習,在記錄知識的同時獲得部分瀏覽量,得到更多人的認可,滿足小小的成就感,同時在寫博客的途中結交更多志同道合的朋友,讓自己在技術的路上并不孤單。

目錄:
1.求最短路徑的兩種算法簡介
2.迪杰斯特拉(Dijkstra 算法)
???? ?? 迪杰斯特拉算法簡介
???? ?? 迪杰斯特拉算法代碼實現(C完整代碼)
???? ?? 迪杰斯特拉算法小結
3.弗洛伊德算法
???? ?? 弗洛伊德算法簡介
???? ?? 迪杰斯特拉算法代碼實現(C完整代碼)
???? ?? 弗洛伊德算法小結

1.求最短路徑的兩種算法簡介

在一個網(有權圖)中,求一個頂點到另一個頂點的最短路徑的計算方式有兩種:迪杰斯特拉(Dijkstra 算法)和弗洛伊德(Floyd)算法。迪杰斯特拉算法計算的是有向網中的某個頂點到其余所有頂點的最短路徑;弗洛伊德算法計算的是任意兩頂點之間的最短 路徑最短路徑算法既適用于有向網,也同樣適用于無向網。本節將圍繞有向網講解迪杰斯特拉算法的具體實現

2.迪杰斯特拉(Dijkstra 算法)

2.1迪杰斯特拉算法簡介

迪杰斯特拉算法計算的是從網中一個頂點到其它頂點之間的最短路徑問題


如圖 所示是一個有向網,在計算 V0 到其它所有頂點之間的最小路徑時,迪杰斯特拉算法的計算方式為:

從 V0 出發,由于可以直接到達 V2 、V3和 V5 ,而其它頂點和 V0 之間沒有弧的存在,所以之間的距離設定為無窮大,可以得到 下面這個表格:

從表格中可以看到,V0 到 V2 的距離最近,所以迪杰斯特拉算法設定 V0-V2 為 V0 到 V2 之間的最短路徑,最短路徑的權 值和為 10

已經判斷 V0-V2 是最短路徑,所以以 V2 為起始點,判斷 V2 到除了 V0 以外的其余各點之間的距離,如果對應的權值比前 一張表格中記錄的數值小,就說明網中有一條更短的路徑,直接更新表格;反之表格中的數據不變。可以得到下面這個表格:

例如,表格中 V0 到 V3 的距離,發現當通過 V2 到達 V3 的距離比之前的 ∞ 要小,所以更新表格。

更新之后,發現 V0-V4 的距離最近,設定 V0 到 V4 的最短路徑的值為 30。之后從 V4 出發,判斷到未確定最短路徑的其 它頂點的距離,繼續更新表格

更新后確定從 V0 到 V3 的最短路徑為 V0-V4-V3,權值為 50。然后從 V3 出發,繼續判斷:

對于 V5 來說,通過 V0-V4-V3-V5 的路徑要比之前的權值 90 還要小,所以更新表格,更新后可以看到,V0-V5 的距離此時 最短,可以確定 V0 到 V5 的最短路徑為 60。

最后確定 V0-V1 的最短路徑,由于從 V0 無法到達 V1 ,最終設定 V0 到 V1 的最短路徑為 ∞(無窮大)。在確定了 V0 與其他所有頂點的最短路徑后,迪杰斯特拉算法才算結束。

實際上無向網中的最短路徑問題也可以使用迪杰斯特拉算法解決, 解決過程和上述過程完全一致。

2.2迪杰斯特拉算法代碼實現(C完整代碼)

#include <stdio.h> #define MAX_VERtEX_NUM 20 //頂點的最大個數 #define VRType int //表示弧的權值的類型 #define VertexType int //圖中頂點的數據類型 #define INFINITY 65535 typedef struct {VertexType vexs[MAX_VERtEX_NUM]; //存儲圖中頂點數據VRType arcs[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; //二維數組,記錄頂點之間的關系int vexnum,arcnum; //記錄圖的頂點數和弧(邊)數 }MGraph; typedef int PathMatrix[MAX_VERtEX_NUM]; //用于存儲最短路徑中經過的頂點的下標 typedef int ShortPathTable[MAX_VERtEX_NUM]; //用于存儲各個最短路徑的權值和 //根據頂點本身數據,判斷出頂點在二維數組中的位置 int LocateVex(MGraph * G,VertexType v){int i=0;//遍歷一維數組,找到變量 vfor (; i<G->vexnum; i++) {if (G->vexs[i]==v) {break;}} //如果找不到,輸出提示語句,返回-1 if (i>G->vexnum) {printf("no such vertex.\n"); return -1;}return i; } //構造有向網 void CreateUDG(MGraph *G){ scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j]=INFINITY;}} for (int i=0; i<G->arcnum; i++) {int v1,v2,w; scanf("%d,%d,%d",&v1,&v2,&w);int n=LocateVex(G, v1);int m=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n"); return;}G->arcs[n][m]=w;} } //迪杰斯特拉算法,v0 表示有向網中起始點所在數組中的下標 void ShortestPath_Dijkstra(MGraph G,int v0,PathMatrix *p,ShortPathTable *D){int final[MAX_VERtEX_NUM];//用于存儲各頂點是否已經確定最短路徑的數組 //對各數組進行初始化for (int v=0; v<G.vexnum; v++) {final[v]=0;(*D)[v]=G.arcs[v0][v];(*p)[v]=0; } //由于以 v0 位下標的頂點為起始點,所以不用再判斷(*D)[v0]=0;final[v0]=1;int k = 0;for (int i=0; i<G.vexnum; i++) {int min=INFINITY; //選擇到各頂點權值最小的頂點,即為本次能確定最短路徑的頂點for (int w=0; w<G.vexnum; w++) {if (!final[w]) {if ((*D)[w]<min) {k=w; min=(*D)[w];}} } //設置該頂點的標志位為 1,避免下次重復判斷final[k]=1; //對 v0 到各頂點的權值進行更新for (int w=0; w<G.vexnum; w++) {if (!final[w]&&(min+G.arcs[k][w]<(*D)[w])) {(*D)[w]=min+G.arcs[k][w];(*p)[w]=k;//記錄各個最短路徑上存在的頂點}}} } int main(){MGraph G;CreateUDG(&G);PathMatrix P;ShortPathTable D;ShortestPath_Dijkstra(G, 0, &P, &D);for (int i=1; i<G.vexnum; i++) {printf("V%d - V%d 的最短路徑中的頂點有(逆序):",0,i);printf(" V%d",i);int j=i; //由于每一段最短路徑上都記錄著經過的頂點,所以采用嵌套的方式輸出即可得到各個最短路徑上的所有頂點while (P[j]!=0) {printf(" V%d",P[j]);j=P[j];}printf(" V0\n");}printf("源點到各頂點的最短路徑長度為:\n");for (int i=1; i<G.vexnum; i++) {printf("V%d - V%d : %d \n",G.vexs[0],G.vexs[i],D[i]);}return 0; }

對于本例子:

輸入 6,8 0 1 2 3 4 5 0,5,100 0,4,30 0,2,10 1,2,5 2,3,50 3,5,10 4,3,20 4,5,60 //輸出 V0 - V1 的最短路徑中的頂點有: V1 V0 V0 - V2 的最短路徑中的頂點有: V2 V0 V0 - V3 的最短路徑中的頂點有: V3 V4 V0 V0 - V4 的最短路徑中的頂點有: V4 V0 V0 - V5 的最短路徑中的頂點有: V5 V3 V4 V0 源點到各頂點的最短路徑長度為: V0 - V1 : 65535 V0 - V2 : 10 V0 - V3 : 50 V0 - V4 : 30 V0 - V5 :

2.3迪杰斯特拉算法小結

迪杰斯特拉算法解決的是從網中的一個頂點到所有其它頂點之間的最短路徑,算法整體的時間復雜度為 O(n2)。但是如果需要求 任意兩頂點之間的最短路徑,使用迪杰斯特拉算法雖然最終雖然也能解決問題,但是大材小用,相比之下使用弗洛伊德算法解決 此類問題會更合適。

3.弗洛伊德算法

3.1弗洛伊德算法簡介

弗洛伊德的核心思想是:對于網中的任意兩個頂點(例如頂點 A 到頂點 B)來說,之間的最短路徑不外乎有 2 種情況:

  • 直接從頂點 A 到頂點 B 的弧的權值為頂點 A 到頂點 B 的最短路徑;
  • 從頂點 A 開始,經過若干個頂點,最終達到頂點 B,期間經過的弧的權值和為頂點 A 到頂點 B 的最短路徑。
  • 所以,弗洛伊德算法的核心為:對于從頂點 A 到頂點 B 的最短路徑,拿出網中所有的頂點進行如下判斷:

    Dis(A,K)+ Dis(K,B)< Dis(A,B)

    其中,K 表示網中所有的頂點;Dis(A,B) 表示頂點 A 到頂點 B 的距離。

    也就是說,拿出所有的頂點 K,判斷經過頂點 K 是否存在一條可行路徑比直達的路徑的權值小,如果式子成立,說明確實存在一條權值更小的路徑,此時只需要更新記錄的權值和即可。

    任意的兩個頂點全部做以上的判斷,最終遍歷完成后記錄的最終的權值即為對應頂點之間的最短路徑

    如下圖:

    例如,在使用弗洛伊德算法計算上圖中的任意兩個頂點之間的最短路徑時,具體實施步驟為: 首先,記錄頂點之間初始的權值,如下表所示:

    依次遍歷所有的頂點,假設從 V0 開始,將 V0 作為中間點,看每對頂點之間的距離值是否會更小。最終 V0 對于每對頂點之 間的距離沒有任何改善。

    對于 V0 來說,由于該頂點只有出度,沒有入度,所以沒有作為中間點的可能。同理,V1 也沒有可能。

    將 V2 作為每對頂點的中間點,有影響的為 (V0,V3) 和 (V1,V3):
    例如,(V0,V3)權值為無窮大,而(V0,V2)+(V2,V3)= 60,比之前的值小,相比而言后者的路徑更短;同理 (V1, V3)也是如此。

    更新的表格為:

    以 V3 作為中間頂點遍歷各隊頂點,更新后的表格為:

    以 V4 作為中間頂點遍歷各隊頂點,更新后的表格為:

    而對于頂點 V5 來說,和頂點 V0 和 V1 相類似,所不同的是,V5 只有入度,沒有出度,所以對各隊頂點的距離不會產生影 響。最終采用弗洛伊德算法求得的各個頂點之間的最短路徑如上圖所示。

    3.2弗洛伊德算法代碼實現(C語言完整代碼)

    #include <stdio.h> #define MAX_VERtEX_NUM 20 //頂點的最大個數 #define VRType int //表示弧的權值的類型 #define VertexType int //圖中頂點的數據類型 #define INFINITY 65535 typedef struct {VertexType vexs[MAX_VERtEX_NUM]; //存儲圖中頂點數據VRType arcs[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; //二維數組,記錄頂點之間的關系int vexnum,arcnum; //記錄圖的頂點數和弧(邊)數 }MGraph; typedef int PathMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; //用于存儲最短路徑中經過的頂點的下標 typedef int ShortPathTable[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; //用于存儲各個最短路徑的權值和 //根據頂點本身數據,判斷出頂點在二維數組中的位置 int LocateVex(MGraph * G,VertexType v){int i=0; //遍歷一維數組,找到變量 vfor (; i<G->vexnum; i++) {if (G->vexs[i]==v) {break;}} //如果找不到,輸出提示語句,返回-1if (i>G->vexnum) {printf("no such vertex.\n"); return -1;}return i;} //構造有向網 void CreateUDG(MGraph *G){ scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) { scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j]=INFINITY;}} for (int i=0; i<G->arcnum; i++) {int v1,v2,w;scanf("%d,%d,%d",&v1,&v2,&w);int n=LocateVex(G, v1);int m=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n"); return;}G->arcs[n][m]=w;} } //弗洛伊德算法,其中 P 二維數組存放各對頂點的最短路徑經過的頂點,D 二維數組存儲各個頂點之間的權值 void ShortestPath_Floyed(MGraph G,PathMatrix *P,ShortPathTable *D){ //對 P 數組和 D 數組進行初始化for (int v=0; v<G.vexnum; v++) {for (int w=0; w<G.vexnum; w++) {(*D)[v][w]=G.arcs[v][w];(*P)[v][w]=-1;}}//拿出每個頂點作為遍歷條件for (int k=0; k<G.vexnum; k++) { //對于第 k 個頂點來說,遍歷網中任意兩個頂點,判斷間接的距離是否更短for (int v=0; v<G.vexnum; v++) {for (int w=0; w<G.vexnum; w++) { //判斷經過頂點 k 的距離是否更短,如果判斷成立,則存儲距離更短的路徑if ((*D)[v][w] > (*D)[v][k] + (*D)[k][w]) {(*D)[v][w]=(*D)[v][k] + (*D)[k][w];(*P)[v][w]=k;}}}} } int main(){MGraph G;CreateUDG(&G);PathMatrix P;ShortPathTable D;ShortestPath_Floyed(G, &P, &D);for (int i=0; i<G.vexnum; i++) {for (int j=0; j<G.vexnum; j++) {printf("%d ",P[i][j]);}printf("\n");}for (int i=0; i<G.vexnum; i++) {for (int j=0; j<G.vexnum; j++) {printf("%d ",D[i][j]);}printf("\n");}return 0; }

    對于這個例子

    //輸入 6,8 0 1 2 3 4 5 0,5,100 0,4,30 0,2,10 1,2,5 2,3,50 3,5,10 4,3,20 4,5,60 //輸出 -1 -1 -1 4 -1 4 -1 -1 -1 2 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 65535 65535 10 50 30 60 65535 65535 5 55 65535 65 65535 65535 65535 50 65535 60 65535 65535 65535 65535 65535 10 65535 65535 65535 20 65535 30 65535 65535 65535 65535 65535 65535

    3.3弗洛伊德算法小結

    迪杰斯特拉主要解決從網(帶權圖)中某一頂點計算到其它頂點之間的最短路徑問題。如果求有向網 中每一對頂點之間的最短路徑,使用迪杰斯特拉算法的解決思路是:以每一個頂點為源點,執行迪杰斯特拉算法。這樣可以求得 每一對頂點之間的最短路徑。也可以使用弗洛伊德算法,該算法相比于使用迪杰斯特拉算法在解決此問題上的時間復雜度雖然相同,都為 O(n3),但是弗洛伊德算法的實現形式更簡單。

    本篇博客轉載C語言中文網

    總結

    以上是生活随笔為你收集整理的最短路径之迪杰斯特拉(Dijkstra 算法)弗洛伊德算法(C语言完整代码实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 潘金莲三级80分钟 | 白白色视频在线 | 国产不卡视频一区二区三区 | 成年人视频在线免费看 | 少妇性l交大片 | 粉嫩av蜜桃av蜜臀av | 欧美亚洲一区二区三区四区 | 欧美人妻精品一区二区免费看 | 美女隐私免费网站 | 亚洲 小说区 图片区 | 中文字幕av无码一区二区三区 | 一区二区三区高清不卡 | 亚洲综合日韩在线 | 91精品推荐| 欧美日韩国产中文 | 一区二区三区视频在线免费观看 | 厕拍极品 | 日韩国产欧美在线观看 | 操大逼网站 | 先锋成人 | 成人91视频| 日韩电影在线观看一区二区 | 91高清视频| 久久精品视频2 | 久久久人体| 日本在线免费 | 国产欧美一区二区精品忘忧草 | 成人www视频| 国产精品热久久 | 欧美一区高清 | 色狠狠av | 最新亚洲精品 | 偷拍一区二区 | 日韩在观看线 | 外国电影免费观看高清完整版 | 中文字幕二区三区 | 亚洲AV午夜福利精品一级无码 | 国产一区二区三区在线 | 亚洲成人福利在线 | 欧美成人h版在线观看 | 亚久久| 99精品一区二区三区 | 欧美日韩极品 | 国产精品亚洲一区二区三区在线观看 | 日本一级淫片色费放 | 精品视频久久久久久久 | 2024国产精品视频 | 中日韩在线视频 | 国产日韩欧美久久 | 激情专区| 光棍天堂av | 国产孕妇孕交大片孕 | 青青草五月天 | 欧美日韩六区 | 日韩欧美一区在线观看 | 成人乱码一区二区三区av | 黄色小说网站在线观看 | 少妇裸体挤奶汁奶水视频 | 日韩精品一区二区三区中文在线 | 日韩少妇中文字幕 | 午夜精品久久久 | 日本丰满熟妇bbxbbxhd | 麻豆网站入口 | 在线免费播放 | 国产人人爽 | 91av视频网站 | 丁香综合网 | 亚洲我射av | 久久99网站 | 少妇被躁爽到高潮无码人狍大战 | 日本欧美激情 | 国产精品探花一区二区在线观看 | 看特级毛片 | 国产又粗又猛又黄又爽 | 无码少妇精品一区二区免费动态 | 日本aa视频| 国产精品美女久久久网av | 亚洲精品无码久久久久久久 | 国产精品一区二区免费 | 日韩欧美第一页 | 国产午夜久久 | 国产美女无遮挡免费视频 | 成人午夜剧场视频网站 | www噜噜噜 | 性欧美又大又长又硬 | 亚洲欧美日韩在线一区二区 | 91色| 国产激情二区 | 色多多av | 哪个网站可以看毛片 | 悟空影视大全免费高清观看在线 | 精品无码av一区二区三区不卡 | 91成人一区二区三区 | 性生交大片免费看女人按摩 | 99热成人| 国产视频九色蝌蚪 | 女同一区二区三区 | 亚洲成人一二三区 | 亚洲成人动漫在线观看 |