[图] 6.2.2 Dijkstra算法|迪杰斯特拉算法 - 求两个顶点间的最短路径 - C实现

原理与案例:https://blog.csdn.net/summer_dew/article/details/81582989

求两个顶点间的最短路径

相关数据结构

  • dist[v]:起点到未被并入顶点v的最短距离
  • path[v]:起点到v的最短路径中,v的前一个结点
    【特殊值】path[v]=-1:起点到v的最短路径中,v没有前一个结点了
  • set[v]:v已并入则set[v]=1

【注意】path数组是一个一维数组(只存了两个顶点间的最短路径)
这里举的例子是两个顶点间的最短路径,即这个path只记录了一条最短路径–>所以只需要一个一维数组
如下图:path[6]=4,path[4]=5,path[5]=2,path[2]=1,path[1]=0,path[0]=-1停止–>即0到6的最短路径为:6->4->5->2->1->0
《[图] 6.2.2 Dijkstra算法|迪杰斯特拉算法 - 求两个顶点间的最短路径 - C实现》
在上一篇原理中所说,path是一个二维数组–>二维数组的path是记录了起点到任意一个顶点的最短路径),注意区分

实现

【测试数据】
《[图] 6.2.2 Dijkstra算法|迪杰斯特拉算法 - 求两个顶点间的最短路径 - C实现》
【结果】
《[图] 6.2.2 Dijkstra算法|迪杰斯特拉算法 - 求两个顶点间的最短路径 - C实现》

【函数】

void Dijkstra(int n, int MGraph[][maxSize], int start, int end, int dist[], int path[]) {
	int set[maxSize];
	int min,v;
	int i,j;
	
	//初始化
	for (i=0; i<n; i++) {
		dist[i]=MGraph[start][i];
		set[i]=0;
		if (MGraph[start][i]<INF)
			path[i]= start;
		else
			path[i]=-1;
	}
	set[start]=1;path[start]=-1;

	//对剩余的每个顶点进行处理
	for (i=0; i<n-1; ++i) {
		//选出与起点距离最近的点
		min=INF;
		for (j=0; j<n; j++) {
			if (set[j]==0 && dist[j]<min) {
				v=j;
				min=dist[j];
			}
		}
		set[v]=1;
	
		//对dist、path更新
		for (j=0; j<n; ++j) {
			if (set[j]==0 && dist[v]+MGraph[v][j]<dist[j]) {
				dist[j]=dist[v]+MGraph[v][j];
				path[j]=v;
			}
		}

		if (v==end) {
			return ; //找到了start-->end的最短路径
		}
	}
}

完整代码

#include<stdio.h>
#include<stdlib.h>

#define maxSize 10
#define INF 100000

void Dijkstra(int n, int MGraph[][maxSize], int start, int end, int dist[], int path[]) {
	int set[maxSize];
	int min,v;
	int i,j;
	
	//初始化
	for (i=0; i<n; i++) {
		dist[i]=MGraph[start][i];
		set[i]=0;
		if (MGraph[start][i]<INF)
			path[i]= start;
		else
			path[i]=-1;
	}
	set[start]=1;path[start]=-1;

	//对剩余的每个顶点进行处理
	for (i=0; i<n-1; ++i) {
		//选出与起点距离最近的点
		min=INF;
		for (j=0; j<n; j++) {
			if (set[j]==0 && dist[j]<min) {
				v=j;
				min=dist[j];
			}
		}
		set[v]=1;
	
		//对dist、path更新
		for (j=0; j<n; ++j) {
			if (set[j]==0 && dist[v]+MGraph[v][j]<dist[j]) {
				dist[j]=dist[v]+MGraph[v][j];
				path[j]=v;
			}
		}

		if (v==end) {
			return ; //找到了start-->end的最短路径
		}
	}
}

int MGraph[maxSize][maxSize]; //邻接矩阵
char vertex[maxSize];
int main() {
/* 7 ABCDEFG 10000 18 10000 10000 10000 19 18 18 10000 8 10000 10000 10000 20 10000 8 10000 20 10000 10000 10000 10000 10000 20 10000 9 16 15 10000 10000 10000 9 10000 3 10000 19 10000 10000 16 3 10000 15 18 20 10000 15 10000 15 10000 0 1 0 3 */
	int n;
	int i,j;
	char tmp[maxSize+5];
	int start,end;
	int dist[maxSize],path[maxSize];

	scanf("%d", &n); //结点数
	scanf("%s", tmp); //结点信息
	for (i=0; i<n; i++)
		vertex[i] = tmp[i];
	for (i=0; i<n; i++) { //矩阵
		for (j=0; j<n; j++) {
			scanf("%d", &MGraph[i][j]);
		}
	}
	while (1) {
		printf("\n\n>>> 输入两个顶点下标(空格分割):");
		scanf("%d %d" , &start,&end); //输入两个测试的顶点,求v->w的最短路径
		Dijkstra(n, MGraph, start, end, dist, path);

		printf("结点\t");
		for (i=0; i<n; i++) {
			printf("%c\t", vertex[i]);
		}
		printf("\n下标\t");
		for (i=0; i<n; i++) {
			printf("%d\t", i);
		}
		printf("\ndist:");
		for (i=0; i<n; i++) {
			printf("%d\t", dist[i]);
		}
		printf("\npath:");
		for (i=0; i<n; i++) {
			printf("%d\t", path[i]);
		}
		printf("\n-- %d到%d结点的最短路径(反过来输出):", start, end);
		for (i=end; path[i]!=-1; i=path[i]) {
			printf("%c <- ", vertex[i]);
		}
		printf("%c\n", vertex[i]);
	}
	return 0;
}
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/summer_dew/article/details/81583010
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞