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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ 遍历所有点且距离最短_C/C++ 图的最短路径 Dijkstra 算法

發(fā)布時間:2023/12/19 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 遍历所有点且距离最短_C/C++ 图的最短路径 Dijkstra 算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:小石王

鏈接:https://www.cnblogs.com/xiaoshiwang/p/9442391.html

圖的最短路徑的概念:

一位旅客要從城市A到城市B,他希望選擇一條途中中轉(zhuǎn)次數(shù)最少的路線。假設(shè)途中每一站都需要換車,則這個問題反映到圖上就是要找一條從頂點A到B所含邊的數(shù)量最少的路徑。我們只需從頂點A出發(fā)對圖作廣度優(yōu)先遍歷,一旦遇到頂點B就終止。由此所得廣度優(yōu)先生成樹上,從根頂點A到頂點B的路徑就是中轉(zhuǎn)次數(shù)最少的路徑。但是這只是一類最簡單的圖的最短路徑問題。有時,對于旅客來說,可能更關(guān)心的是節(jié)省交通費用;而對于司機(jī)來說,里程和速度則是他們感興趣的的信息。為了在圖上表示相關(guān)信息,可對邊賦以權(quán)值,權(quán)值可以表示兩個城市之間的距離,或途中所需時間,或交通費用等等。此時路徑長度的度量就不再是路徑上邊的數(shù)目,而是路徑上邊權(quán)值之和。

實現(xiàn)思路:

  • 創(chuàng)建2個輔助int*數(shù)組dist path,1個bool數(shù)組s

  • dist 存放目標(biāo)頂點到每個頂點的最短距離

  • path 存放目標(biāo)頂點到每個頂點的路徑

  • s 被查找過的頂點設(shè)置為true,否則為false

圖為下圖

1、假設(shè)目標(biāo)頂點為A,先從A開始找到各個頂點的權(quán)值,

ABCDE
dist010無窮大30100
path-10000
struefalsefalsefalsefalse

path含義:比如path[1]=0,就代表從下標(biāo)為0的頂點(A頂點)到B頂點

2、從dist里找到s為false的最小值,也就是dist[1]的值10,下標(biāo)1說明是頂點B,再從B開始找到各個頂點的權(quán)值,更新dist和path,并設(shè)置B為true

ABCDE
dist0106030100
path-10100
struetruefalsefalsefalse

3、從dist里找到s為false最小值,也就是dist[3]的值30,下標(biāo)3說明是頂點D,再從D開始找到各個頂點的權(quán)值,更新dist和path,并設(shè)置D為true

ABCDE
dist010503090
path-10303
struetruefalsetruefalse

4、從dist里找到s為false最小值,也就是dist[2]的值50,下標(biāo)2說明是頂點C,再從C開始找到各個頂點的權(quán)值,更新dist和path,并設(shè)置C為true

ABCDE
dist010503060
path-10302
struetruetruetruefalse

5、從dist里找到s為false最小值,也就是dist[4]的值60,下標(biāo)4說明是頂點E,再從E開始找到各個頂點的權(quán)值,更新dist和path,并設(shè)置E為true

ABCDE
dist010503060
path-10302
struetruetruetruetrue

下面兩幅圖可以幫助理解

dijkstra.h

#ifndef?__mixspantree__
#define?__mixspantree__

#include?
#include?
#include?
#include?
#include?
#include?

#define?Default_vertex_size?20

#define?T?char//dai?biao?ding?dian?de?lei?xing
#define?E?int
#define?MAX_COST?0x7FFFFFFF


typedef?struct?GraphMtx{
??int?MaxVertices;//zui?da?ding?dian?shu?liang]
??int?NumVertices;//shi?ji?ding?dian?shu?liang
??int?NumEdges;//bian?de?shu?lian

??T*?VerticesList;//ding?dian?list
??int**?Edge;//bian?de?lian?jie?xin?xi,?bu?shi?0?jiu?shi?1
}GraphMtx;

//chu?shi?hua?tu
void?init_graph(GraphMtx*?gm);
//打印二維數(shù)組
void?show_graph(GraphMtx*?gm);
//插入頂點
void?insert_vertex(GraphMtx*?gm,?T?v);
//添加頂點間的線
void?insert_edge(GraphMtx*?gm,?T?v1,?T?v2,?E?cost);

//最短路徑
void?short_path(GraphMtx*?g,T?v,E*?dist,?int*?path);
#endif

dijkstra.c

#include?"dijkstra.h"

void?init_graph(GraphMtx*?gm){
??gm->MaxVertices?=?Default_vertex_size;
??gm->NumEdges?=?gm->NumVertices?=?0;

??//kai?pi?ding?dian?de?nei?cun?kong?jian
??gm->VerticesList?=?(T*)malloc(sizeof(T)?*?(gm->MaxVertices));
??assert(NULL?!=?gm->VerticesList);

??//創(chuàng)建二維數(shù)組
??//讓一個int的二級指針,指向一個有8個int一級指針的數(shù)組
??//開辟一個能存放gm->MaxVertices個int一級指針的內(nèi)存空間
??gm->Edge?=?(int**)malloc(sizeof(int*)?*?(gm->MaxVertices));
??assert(NULL?!=?gm->Edge);
??//開辟gm->MaxVertices組,能存放gm->MaxVertices個int的內(nèi)存空間
??for(int?i?=?0;?i?MaxVertices;?++i){
????gm->Edge[i]?=?(int*)malloc(sizeof(int)?*?gm->MaxVertices);
??}
??//初始化二維數(shù)組
??//讓每個頂點之間的邊的關(guān)系都為不相連的
??for(int?i?=?0;?i?MaxVertices;?++i){
????for(int?j?=?0;?j?MaxVertices;?++j){
??????if(i?==?j)
????gm->Edge[i][j]?=?0;
??????else
????gm->Edge[i][j]?=?MAX_COST;
????}
??}
}
//打印二維數(shù)組
void?show_graph(GraphMtx*?gm){
??printf("??");
??for(int?i?=?0;?i?NumVertices;?++i){
????printf("%3c??",?gm->VerticesList[i]);
??}
??printf("\n");
??for(int?i?=?0;?i?NumVertices;?++i){
????//在行首,打印出頂點的名字
????printf("%c:",?gm->VerticesList[i]);
????for(int?j?=?0;?j?NumVertices;?++j){
??????if(gm->Edge[i][j]?==?MAX_COST){
????printf("%3c??",?'*');
??????}
??????else{
????printf("%3d??",?gm->Edge[i][j]);
??????}
????}
????printf("\n");
??}
??printf("\n");
}
//插入頂點
void?insert_vertex(GraphMtx*?gm,?T?v){
??//頂點空間已滿,不能再插入頂點了
??if(gm->NumVertices?>=?gm->MaxVertices){
????return;
??}
??gm->VerticesList[gm->NumVertices++]?=?v;
}

int?getVertexIndex(GraphMtx*?gm,?T?v){
??for(int?i?=?0;?i?NumVertices;?++i){
????if(gm->VerticesList[i]?==?v)return?i;
??}
??return?-1;
}
//添加頂點間的線
void?insert_edge(GraphMtx*?gm,?T?v1,?T?v2,?E?cost){
??if(v1?==?v2)return;

??//查找2個頂點的下標(biāo)
??int?j?=?getVertexIndex(gm,?v1);
??int?k?=?getVertexIndex(gm,?v2);
??//說明找到頂點了,并且點之間還沒有線
??if(j?!=?-1?&&?k?!=?-1?){
????//因為是有方向,所以更新1個值
????gm->Edge[j][k]?=?cost;
????//邊數(shù)加一
????gm->NumEdges++;
??}
}

//取得2個頂點之間的權(quán)值
E?getWeight(GraphMtx*?g,?int?v1,?int?v2){
??if(v1?==?-1?||?v2?==?-1)?return?MAX_COST;
??return?g->Edge[v1][v2];
}
//最短路徑
void?short_path(GraphMtx*?g,T?v,E*?dist,?int*?path){
??int?n?=?g->NumVertices;
??bool*?s?=?(bool*)malloc(sizeof(bool)?*?n);
??assert(NULL?!=?s);

??int?vi?=?getVertexIndex(g,?v);
??for(int?i?=?0;?i?????//獲得各個頂點與目標(biāo)頂點之間的權(quán)值
????dist[i]?=?getWeight(g,?vi,?i);
????s[i]?=?false;
????if(i?!=?vi?&&?dist[i]???????path[i]?=?vi;
????}
????else{
??????path[i]?=?-1;
????}
??}

??s[vi]?=?true;
??int?min;
??int?w;
??for(int?i?=?0;?i?1;?++i){
????min?=?MAX_COST;
????//u為最短路徑頂點的下標(biāo)
????int?u?=?vi;
????for(int?j?=?0;?j???????if(!s[j]?&&?dist[j]?????u?=?j;
????min?=?dist[j];
??????}
????}
????//把u加入到s集合
????s[u]?=?true;

????//更新下一個點到所有點的權(quán)值
????for(int?k?=?0;?k???????w?=?getWeight(g,?u,?k);
??????if(!s[k]?&&?w?????dist[k]?=?dist[u]?+?w;
????path[k]?=?u;
??????}
????}
??}
}

dijkstramain.c

#include?"dijkstra.h"

int?main(){
??GraphMtx?gm;
??//初始化圖
??init_graph(&gm);
??//插入頂點
??insert_vertex(&gm,?'A');
??insert_vertex(&gm,?'B');
??insert_vertex(&gm,?'C');
??insert_vertex(&gm,?'D');
??insert_vertex(&gm,?'E');

??//添加連線
??insert_edge(&gm,?'A',?'B',?10);
??insert_edge(&gm,?'A',?'D',?30);
??insert_edge(&gm,?'A',?'E',?100);
??insert_edge(&gm,?'B',?'C',?50);
??insert_edge(&gm,?'C',?'E',?10);
??insert_edge(&gm,?'D',?'C',?20);
??insert_edge(&gm,?'D',?'E',?60);
??//打印圖
??show_graph(&gm);

??int?n?=?gm.NumVertices;
??E*?dist?=?(E*)malloc(sizeof(E)?*?n);
??int*?path?=?(int*)malloc(sizeof(int)?*?n);
??assert(NULL?!=?dist?&&?NULL?!=?path);

??//最短路徑
??short_path(&gm,?'A',?dist,?path);

}

完整代碼

https://github.com/yuebaixiao/Data-Struct/tree/master/dijkstra

編譯方法:gcc -g dijkstra.c dijkstramain.c


執(zhí)行結(jié)果如下圖:


●編號495,輸入編號直達(dá)本文

●輸入m獲取文章目錄

C語言與C++編程

分享C/C++技術(shù)文章

總結(jié)

以上是生活随笔為你收集整理的c++ 遍历所有点且距离最短_C/C++ 图的最短路径 Dijkstra 算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。