1. 程式人生 > >C語言弗洛伊德演算法的實現

C語言弗洛伊德演算法的實現

弗洛伊德演算法和迪傑斯特拉演算法一樣,用於求兩個節點之間的最短路徑,過程也比迪傑斯特拉演算法更為簡單。以下是實現程式碼:

首先仍然是預定義和型別定義:

#define OK 1
#define ERROR 0
#define Max_Int 37262
#define MVNum 100

typedef int Status;
typedef char VerTexType;
typedef int ArcType;

typedef struct{
	VerTexType vex[MVNum];
	ArcType arc[MVNum][MVNum];
	int vexnum, arcnum;
}AMGraph;

並定義兩個二維陣列:

int Path[MVNum][MVNum];
ArcType D[MVNum][MVNum];

建立有向圖:

int LocateVex(AMGraph *G, VerTexType v)
{
	int i;
	for (i = 0; i < G->vexnum; i++)
	{
		if (G->vex[i] == v)
			return i;
	}
	return -1;
}

Status CreateUDN(AMGraph *G)
{
	VerTexType v1, v2;
	ArcType w;
	int i, j, k;
	printf("輸入總節點數、總邊數:");
	scanf("%d %d", &G->vexnum, &G->arcnum);
	printf("輸入節點的值:");
	fflush(stdin);
	for (i = 0; i < G->vexnum; i++)
	{
		scanf("%c", &G->vex[i]);
	}
	for (i = 0; i < G->vexnum; i++)
	for (j = 0; j < G->vexnum; j++)
	{
		G->arc[i][j] = Max_Int;
	}
	for (k = 0; k < G->arcnum; k++)
	{
		fflush(stdin);
		printf("依次輸入邊的兩個頂點以及邊的權值:");
		scanf("%c %c %d", &v1, &v2, &w);
		i = LocateVex(G, v1);
		j = LocateVex(G, v2);
		G->arc[i][j] = w;
	}
	return OK;
}

弗洛伊德演算法:

void ShortestPath_Floyd(AMGraph G)
{
	int i, j, k;
	for (i = 0; i < G.vexnum;i++)
	for (j = 0; j < G.vexnum; j++)
	{
		D[i][j] = G.arc[i][j];
		if (D[i][j] < Max_Int)
			Path[i][j] = i;
		else
			Path[i][j] = -1;
	}
	for (k = 0; k < G.vexnum;k++)
	for (i = 0; i < G.vexnum;i++)
	for (j = 0; j < G.vexnum; j++)
	{
		if (D[i][j]>D[i][k] + D[k][j])
		{
			D[i][j] = D[i][k] + D[k][j];
			Path[i][j] = Path[k][j];
		}
	}
}

初始化:將D[i][j]賦值為i,j邊的權值,並判斷其權值若不為最大值(Max_Int),則將Path[i][j]賦值為0,否則賦值為-1.

依次判斷i,j下標的邊的權值是否大於i、k和k、j下標邊的權值之和,若大於,則說明目前記錄的並非最短路徑,將i、k和k、j下標邊的權值之和賦值給D[i][k],並將Path[k][j]賦值給Path[i][j]。

加入main():


int main(void)
{
	int i, j;
	AMGraph G;
	CreateUDN(&G);
	ShortestPath_Floyd(G);
	for (i = 1; i < G.vexnum; i++)
	{
		if (D[0][i] == Max_Int)
			printf("0無法到達%c\n", G.vex[i]);
		else
			printf("0到%c的權值為:%d\n", G.vex[i], D[0][i]);
	}
	return 0;
}