C語(yǔ)言實(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)行通過(guò)。
#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)名稱(chēng)(輸入格式為: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)名稱(chēng)(輸入格式為:a,b):\n");
for(k=0;k<G->arcnum;k++)
{
// getchar();
printf("請(qǐng)輸入第%d條邊的兩個(gè)頂點(diǎn)名稱(chēng):",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)過(guò)下標(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)。
在編寫(xiě)過(guò)程中遇到了以下錯(cuò)誤:
在62行
[Error]subscripted value is neither array nor pointer nor vector
意思是
下標(biāo)的值不是數(shù)組或指針或向量
當(dāng)時(shí)我這一行是這樣寫(xiě)的
void ShortestPath_Floyd(MGraph G,int** P,int** D)
因?yàn)樵谏弦黄恼翫ijkstra算法中一維數(shù)組作為函數(shù)參數(shù)是用的int*,沒(méi)有問(wèn)題
所以在這里二維數(shù)組我就想當(dāng)然地用了int**
但是如果參數(shù)傳入int**類(lèi)型,在函數(shù)里就不能使用P[v][w]訪問(wèn)二維數(shù)組的值
編譯器不能正確為它尋址,需要模仿編譯器的行為把P[v][w]這樣的式子手工轉(zhuǎn)變?yōu)椋?/p>
*((int*)P + n*v + w);
所以在被調(diào)用函數(shù)中對(duì)形參數(shù)組定義時(shí)可以指定所有維數(shù)的大小,也可以省略第一維的大小說(shuō)明
故改為void ShortestPath_Floyd(MGraph G,int P[9][9],int D[9][9])就可以編譯通過(guò)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C 語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 web 服務(wù)器的原理解析
這篇文章主要介紹了C 語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 web 服務(wù)器的原理解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
C語(yǔ)言中隊(duì)列的結(jié)構(gòu)和函數(shù)接口的使用示例
隊(duì)列只允許一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作的特殊線性表,隊(duì)列具有先進(jìn)先出FIFO的性質(zhì);隊(duì)列可用數(shù)組和鏈表 的方法實(shí)現(xiàn),使用鏈表的結(jié)構(gòu)實(shí)現(xiàn)更優(yōu)一些,因?yàn)槿绻褂脭?shù)組節(jié),出隊(duì)列時(shí)刪去首元素需要將整個(gè)數(shù)組前移,效率比較低2023-02-02
VC++植物大戰(zhàn)僵尸中文版修改器實(shí)現(xiàn)代碼
這篇文章主要介紹了VC++植物大戰(zhàn)僵尸中文版修改器實(shí)現(xiàn)代碼,可實(shí)現(xiàn)植物大戰(zhàn)僵尸中的無(wú)限陽(yáng)光與無(wú)冷卻時(shí)間功能,需要的朋友可以參考下2015-04-04
C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
詳解C語(yǔ)言中scanf函數(shù)使用的一些注意點(diǎn)
這篇文章主要介紹了C語(yǔ)言中scanf函數(shù)使用的一些注意點(diǎn),scanf函數(shù)的使用是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-04-04
C++回文數(shù)及素?cái)?shù)問(wèn)題計(jì)算方法
這篇文章主要介紹了C++回文數(shù)及素?cái)?shù)問(wèn)題計(jì)算方法,可實(shí)現(xiàn)一定范圍內(nèi)的素?cái)?shù)與回文數(shù)運(yùn)算功能,涉及C++字符串遍歷與數(shù)字?jǐn)?shù)學(xué)運(yùn)算的相關(guān)技巧,需要的朋友可以參考下2016-05-05

