C語言實(shí)現(xiàn)圖的最短路徑Floyd算法
Floyd算法直接使用二維數(shù)組求出所有頂點(diǎn)到所有頂點(diǎn)的最短路徑。
D代表頂點(diǎn)到頂點(diǎn)的最短路徑權(quán)值和的矩陣。
P代表對(duì)應(yīng)頂點(diǎn)的最小路徑的前驅(qū)矩陣。
以下程序在DEV C++中調(diào)試運(yùn)行通過。
#include <stdio.h> #define INFINITY 65535 typedef int VertexType; //頂點(diǎn)是字符型 typedef int EdgeType; //邊是整型 typedef struct //圖的鄰接矩陣存儲(chǔ)結(jié)構(gòu) { VertexType vexs[9]; //頂點(diǎn)向量 EdgeType edges[9][9]; //鄰接矩陣 int vexnum,arcnum; //圖中當(dāng)前的頂點(diǎn)數(shù)和邊數(shù) }MGraph; /* 鄰接矩陣的建立*/ void CreateGraph(MGraph *G) { int i,j,k,weight; int ch1,ch2; printf("請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù)(輸入格式為:頂點(diǎn)數(shù),邊數(shù)):"); scanf("%d,%d",&(G->vexnum),&(G->arcnum)); printf("請(qǐng)輸入頂點(diǎn)名稱(輸入格式為:a,b,c...):"); for(i=0;i<G->vexnum;i++) { getchar(); scanf("%d",&(G->vexs[i])); } for(i=0;i<G->vexnum;i++) for(j=0;j<G->vexnum;j++) if(i==j) G->edges[i][j]=0; else G->edges[i][j]=INFINITY; printf("請(qǐng)輸入每條邊對(duì)應(yīng)的兩個(gè)頂點(diǎn)名稱(輸入格式為:a,b):\n"); for(k=0;k<G->arcnum;k++) { // getchar(); printf("請(qǐng)輸入第%d條邊的兩個(gè)頂點(diǎn)名稱:",k+1); scanf("%d,%d",&ch1,&ch2); for(i=0;ch1!=G->vexs[i];i++); for(j=0;ch2!=G->vexs[j];j++); getchar(); printf("請(qǐng)輸入第%d條邊的權(quán)值:",k+1); scanf("%d",&weight); G->edges[i][j]=weight; G->edges[j][i]=weight; } } void ShortestPath_Floyd(MGraph G,int P[9][9],int D[9][9]) { int v,w,k; for(v=0;v<G.vexnum;v++)//初始化D和P { for(w=0;w<G.vexnum;w++) { D[v][w]=G.edges[v][w]; P[v][w]=w; } } for(k=0;k<G.vexnum;k++) { for(v=0;v<G.vexnum;v++) { for(w=0;w<G.vexnum;w++) { if(D[v][w]>(D[v][k]+D[k][w])) {//如果經(jīng)過下標(biāo)為k頂點(diǎn)路徑比原兩點(diǎn)間路徑更短,將當(dāng)前兩點(diǎn)間權(quán)值設(shè)為更小的一個(gè) D[v][w]=D[v][k]+D[k][w]; P[v][w]=P[v][k]; } } } } } void main() { MGraph G; CreateGraph(&G); int i,j; printf("edgesnum:%d\n",G.arcnum); printf("vexesnum:%d\n",G.vexnum); for(i=0;i<9;i++) { for(j=0;j<9;j++) printf("%d ",G.edges[i][j]); printf("\n"); } int v,w,k; int P[9][9]; int D[9][9]; printf("%d\n",P); printf("%d\n",D); ShortestPath_Floyd(G,P,D); for(v=0;v<G.vexnum;v++)//顯示路徑 { for(w=v+1;w<G.vexnum;w++) { printf("v%d-v%d weight:%d ",v,w,D[v][w]); k=P[v][w]; printf("path:%d",v); while(k!=w) { printf("->%d",k); k=P[k][w]; } printf("->%d\n",w); } } }
運(yùn)行結(jié)果如圖所示。
整個(gè)算法的時(shí)間復(fù)雜度是O(n^3)。
在編寫過程中遇到了以下錯(cuò)誤:
在62行
[Error]subscripted value is neither array nor pointer nor vector
意思是
下標(biāo)的值不是數(shù)組或指針或向量
當(dāng)時(shí)我這一行是這樣寫的
void ShortestPath_Floyd(MGraph G,int** P,int** D)
因?yàn)樵谏弦黄恼翫ijkstra算法中一維數(shù)組作為函數(shù)參數(shù)是用的int*,沒有問題
所以在這里二維數(shù)組我就想當(dāng)然地用了int**
但是如果參數(shù)傳入int**類型,在函數(shù)里就不能使用P[v][w]訪問二維數(shù)組的值
編譯器不能正確為它尋址,需要模仿編譯器的行為把P[v][w]這樣的式子手工轉(zhuǎn)變?yōu)椋?/p>
*((int*)P + n*v + w);
所以在被調(diào)用函數(shù)中對(duì)形參數(shù)組定義時(shí)可以指定所有維數(shù)的大小,也可以省略第一維的大小說明
故改為void ShortestPath_Floyd(MGraph G,int P[9][9],int D[9][9])就可以編譯通過。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)中樹與森林專項(xiàng)詳解
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)中樹與森林,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-11-11先序遍歷二叉樹的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)深入解析
以下是對(duì)先序遍歷二叉樹的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-07-07VisualStudio?制作Dynamic?Link?Library動(dòng)態(tài)鏈接庫文件的詳細(xì)過程
這篇文章主要介紹了VisualStudio?制作Dynamic?Link?Library動(dòng)態(tài)鏈接庫文件的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08c語言實(shí)現(xiàn)輸入一組數(shù)自動(dòng)從大到小排列的實(shí)例代碼
下面小編就為大家?guī)硪黄猚語言實(shí)現(xiàn)輸入一組數(shù)自動(dòng)從大到小排列的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn)
本文主要介紹了openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11C語言手撕一個(gè)Hash表(HashTable)實(shí)例代碼
哈希表(HashTable)是一種非常重要的數(shù)據(jù)結(jié)構(gòu),它可以在常量時(shí)間內(nèi)進(jìn)行插入、查找和刪除操作,下面這篇文章主要給大家介紹了關(guān)于C語言手撕一個(gè)Hash表(HashTable)的相關(guān)資料,需要的朋友可以參考下2023-03-03