Dijkstra算法改进,最短路径,c/c++描述

博客介绍了作者通过研究B站懒猫老师的教学视频,对Dijkstra算法进行优化,只存储终点前一个顶点信息来简化最短路径的存储。实现了Dijkstra2ShortestPath函数计算最短路径,并编写了displayShortestPath函数输出路径。提供的完整代码经过测试,结果正确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  刚才又研究了bilibili懒猫老师的教学视频,对昨天的同样的Dijkstra算法进行改进。
  昨天的文章里,我们用一个结构体变量,来存储两顶点间的最短路径的全部信息。

struct ShortestPath {
	int pathLength ;
	int indexOfVertexInPath[MAXVERTEX];
	int numVertex;
};

  这里的路径是完整路径,包括了路径里的所有顶点下标。
  因为起点到最短路径里每一个顶点的路径都是最短路径(这个结论是我自己总结的,根据例题结果,还请大家一起斟酌,谢谢。这句总结也是程序里组织路径数据的核心理论依据。)所以我们还可以简化对最短路径里顶点信息的存储,只存储终点的前一个顶点位置即可。
  懒猫老师的和课本里的程序,应该是这么个思路。
  函数Dijkstra2ShortestPath:完成对图最短路径的计算,完成对distance[]和indexInPath[]的赋值。数组distance[]存储起点到各顶点的最短路径长度,数组indexInPath[]存储路径终点的前一个顶点在图顶点数组里的下标。
  函数dispalyShortestPath:根据distance[]和indexInPath[]输出图的最短路径。因为其路径存储方式太深奥,故单独编写函数负责输出。
  完整代码如下,先是main函数所在源文件:
  

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXVERTEX 15
#define INFINI 6000

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};

extern void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
			int numVertexes,int numEdges,int edges[][7],char vertexes[]);
extern void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix);
extern void Dijkstra2ShortestPath(GraphAdjaMatrix& graphAdjMatrix,
	int distance[],int indexInPath[], int indexStart);
extern void dispalyShortestPath(GraphAdjaMatrix& graphAdjMatrix,
	int distance[], int indexInPath[], int indexStart);

int main() {
	GraphAdjaMatrix graphAdjMatrix ;
	int numVertexes = 7, numEdges = 12;
	int edges[][7] = {	{0,4,6,6,INFINI,INFINI,INFINI},
						{INFINI,0,1,INFINI,7,INFINI,INFINI},
						{INFINI,INFINI,0,INFINI,6,4,INFINI},
						{INFINI,INFINI,2,0,INFINI,5,INFINI},
						{INFINI,INFINI,INFINI,INFINI,0,INFINI,6},
						{INFINI,INFINI,INFINI,INFINI,1,0,8},
						{INFINI,INFINI,INFINI,INFINI,INFINI,INFINI,0} };
	char vertexes[] = {'0','1','2','3','4','5','6'};

	createGraphAdjMatrix(graphAdjMatrix,numVertexes,numEdges,edges,vertexes);

	dispalyGraphAdjMatrix(graphAdjMatrix);
	cout << endl;

	int distance[MAXVERTEX], indexInPath[MAXVERTEX];
	Dijkstra2ShortestPath(graphAdjMatrix,distance,indexInPath,0);
	
	cout << endl << "shortest path : " << endl;
	dispalyShortestPath(graphAdjMatrix,distance,indexInPath,0);

	return 0;
}

然后是各函数所在源文件:

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXVERTEX 15
#define INFINI 6000

struct GraphAdjaMatrix {
	char vertexes[MAXVERTEX];
	int edges[MAXVERTEX][MAXVERTEX];
	int numVertexes;
	int numEdges;
};



void createGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix,
	int numVertexes, int numEdges, int edges[][7], char vertexes[]) {
	graphAdjMatrix.numVertexes = numVertexes;
	graphAdjMatrix.numEdges = numEdges;
	
	for (int i = 0; i < numVertexes; i++)
		graphAdjMatrix.vertexes[i] = vertexes[i];

	for (int row = 0; row < numVertexes; row++)
		for (int column = 0; column < numVertexes; column++)
			graphAdjMatrix.edges[row][column] = edges[row][column];
}

void dispalyGraphAdjMatrix(GraphAdjaMatrix &graphAdjMatrix) {
	cout << "adjacensy matrix :" << endl;
	int row,column;
	printf("%3c",' ');
	for (row = 0; row < graphAdjMatrix.numVertexes; row++)
		printf("%3c",graphAdjMatrix.vertexes[row]);
	printf("\n");
	for (row = 0; row < graphAdjMatrix.numVertexes; row++) {
		printf("%-3c", graphAdjMatrix.vertexes[row]);
		for (column = 0; column < graphAdjMatrix.numVertexes; column++)
			if (graphAdjMatrix.edges[row][column] == INFINI)
				printf("%3s", "∞");
			else
				printf("%3d",graphAdjMatrix.edges[row][column]);
		cout << endl;
	}
}

void Dijkstra2ShortestPath(GraphAdjaMatrix& graphAdjMatrix,
	int distance[], int indexInPath[], int indexStart) {
	for (int i = 0; i < graphAdjMatrix.numVertexes; i++) {
		distance[i] = graphAdjMatrix.edges[indexStart][i];
		indexInPath[i] = indexStart;
	}

	bool check[MAXVERTEX] = { false };
	check[indexStart] = true;

	int indexUnCheck, indexChecked;
	int shortestTemp, indexTemp;

	for (int pathNum = 1; pathNum <= graphAdjMatrix.numVertexes - 1; pathNum++) {
		for (indexUnCheck = 0; indexUnCheck < graphAdjMatrix.numVertexes; indexUnCheck++) 
			if (check[indexUnCheck] == false)
				for (indexChecked = 0; indexChecked < graphAdjMatrix.numVertexes; indexChecked++)
					if (indexChecked != indexStart && 
						check[indexChecked] == true && 
						graphAdjMatrix.edges[indexChecked][indexUnCheck] != INFINI && 
						distance[indexUnCheck] > distance[indexChecked] + graphAdjMatrix.edges[indexChecked][indexUnCheck]) {
						
						distance[indexUnCheck] = distance[indexChecked] + graphAdjMatrix.edges[indexChecked][indexUnCheck];
						indexInPath[indexUnCheck] = indexChecked;
					}

		shortestTemp = INFINI;
		for(indexUnCheck = 0 ; indexUnCheck < graphAdjMatrix.numVertexes ; indexUnCheck++)
			if (check[indexUnCheck] == false && shortestTemp >= distance[indexUnCheck]) {
				shortestTemp = distance[indexUnCheck];
				indexTemp = indexUnCheck;
			}

		check[indexTemp] = true;
	}
}

void dispalyShortestPath(GraphAdjaMatrix& graphAdjMatrix,
	int distance[], int indexInPath[], int indexStart) {
	char startVertex = graphAdjMatrix.vertexes[indexStart];
	
	char arrayTemp[MAXVERTEX]; 
	int lengthTemp,indexTemp;

	for (int index = 0; index < graphAdjMatrix.numVertexes ; index++) 
		if (index != indexStart) {
			cout << "from " << startVertex << " to " << graphAdjMatrix.vertexes[index] << " , ";
			cout << " path length : ";
			printf("%-2d ,     path : ", distance[index]);
			
			lengthTemp = 0;
			arrayTemp[lengthTemp] = graphAdjMatrix.vertexes[index];
			lengthTemp++;
			indexTemp = indexInPath[index];

			while (indexTemp != indexStart) {
				arrayTemp[lengthTemp] = graphAdjMatrix.vertexes[indexTemp];
				lengthTemp++;
				indexTemp = indexInPath[indexTemp];
			}

			arrayTemp[lengthTemp] = graphAdjMatrix.vertexes[indexTemp];

			for (; lengthTemp >= 0; lengthTemp--)
				cout << arrayTemp[lengthTemp] << " ";

			cout << endl;
		}
}

  测试结果和图和课本结果同上个文章,证明此程序里代码编写也是正确的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
谢谢阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值