# # 最短距离
#基本要求:
设计最短路径,包含以下方面:
1、用邻接矩阵存储一张带权有向图。
2、对图进行从某一源点到其他各顶点的最短路径
3、输出最后结果(路径名称、路径长度)。
信息描述
邻接矩阵建立包括:用二维数组存储信息。没有直达路径的为无穷。
用循环来判断最小值。
最终结果用一维数组存储。
D[]存放源点到其他顶点的最短路径的长度,
P[]存放该顶点最短路径的前驱顶点下标,
visit[]为访问标识。
初始全部值设为F,先把源点的标识设为T,后面每找到一个源点到其余顶点的最短路径,就将该顶点下标对应的标识置为T。直到全部顶点执行完毕。
输出一维数组D[]和P[],显示最终结果。
在这里插入代码片
#include<stdio.h>
#include <iostream>
#define MAX 1000 //定义数组长度
#define INFINITY 1000 //定义无穷
struct Graph {
int VertexNum; //图中顶点个数
char Vertex[MAX]; //将图的顶点字母存入数组
int AdjMatrix[MAX][MAX]; //设置领接矩阵用两个数组
}; Graph MGraph;
char P[MAX][MAX]; //设置图的邻接矩阵
int D[MAX]; //全局设置权值
void CreateGraph(Graph* G); //生成图 调用函数
void ShowGraph(Graph* G); //展示图 调用函数
void ShortestP(Graph* G, char StartVexChar); //测试路径
void ShowP(Graph* G); //展示路径
int main() {
char StartVex;
CreateGraph(&MGraph);
ShowGraph(&MGraph);
printf("请输入开始的顶点:");
std::cin >> StartVex;
ShortestP(&MGraph, StartVex);
ShowP(&MGraph);
return 0;
}
//生成图调用函数
//生成图 调用函数
void CreateGraph(Graph* G) {
int i, j;
printf("请输入顶点个数:\n");
std::cin >> G->VertexNum;//输入顶点数目
printf("请输入顶点:\n");
for (i = 1; i <= G->VertexNum; i++)
std::cin >> G->Vertex[i];//输入顶点
printf("请依次输入邻接矩阵:\n");
for (i = 1; i <= G->VertexNum; i++) {
for (j = 1; j <= G->VertexNum; j++) {
std::cin >> G->AdjMatrix[i][j];//依次输入邻接矩阵
if (G->AdjMatrix[i][j] == -1)
G->AdjMatrix[i][j] = INFINITY;
}
}
}
//展示路径
//展示图 调用函数
void ShowGraph(Graph* G) {
int i, j{};
for (i = 1; i <= G->VertexNum; i++) {
printf("%5c ", G->Vertex[i]);//输出顶点
}
putchar('\n');
for (i = 1; i <= G->VertexNum; i++) {
for (j = 1; j <= G->VertexNum; j++) {
if (G->AdjMatrix[i][j] != INFINITY) {
printf("%5d ", G->AdjMatrix[i][j]);
}
else printf(" ∞");//依次输出邻接矩阵
}
putchar('\n');
}
}
//测试路径
//测试路径
void ShortestP(Graph* G, char StartVexChar) {
int i = 1, j = 0, m = 0, CurrentVex{}, StartVex{}, MinD{}, Final[MAX]{};//当前值,起始值,最小值,最终值
for (i = 1; i <= G->VertexNum; i++) {//找到开始顶点的序号
if (G->Vertex[i] == StartVexChar) {
StartVex = i;
break;
}
}
for (i = 1; i <= G->VertexNum; i++) {
P[i][0] = 0;//顺序表的0位置,存放顺序表(路径)的长度
D[i] = INFINITY;//所有顶点到开始之间的距离初值设为无穷大
if (G->AdjMatrix[StartVex][i] < INFINITY) {//在开始顶点与当前顶点之间存在弧
D[i] = G->AdjMatrix[StartVex][i];
P[i][1] = G->Vertex[StartVex];
P[i][2] = G->Vertex[i];
P[i][0] = 2;
}
Final[i] = 'F';
}
D[StartVex] = 0;//初始化,开始顶点属于已经处理过的顶点
Final[StartVex] = 'T';
for (i = 1; i <= G->VertexNum; i++) {
MinD= INFINITY;
for (j = 1; j <= G->VertexNum; j++) {//寻找当前未处理过的顶点中到开始顶点最近的顶点
if (Final[j] == 'F') {
if (D[j] < MinD) {
CurrentVex = j;
MinD = D[j];
}
}
}
Final[CurrentVex] = 'T';
for (j = 1; j <= G->VertexNum; j++) {//更新当前最短路径和距离
if ((Final[j] == 'F') && (MinD + G->AdjMatrix[CurrentVex][j]) < D[j]) {
D[j] = MinD + G->AdjMatrix[CurrentVex][j];//更新顶点j的最短距离
for (m = 0; m <= P[CurrentVex][0]; m++)//更新顶点j到开始顶点的路径
P[j][m] = P[CurrentVex][m];
P[j][0]++;
P[j][P[j][0]] = G->Vertex[j];
}
}
}
}
//展示路径
//展示路径
void ShowP(Graph* G) {
int i,j{};
for (i = 1; i <= G->VertexNum; i++) {
if (D[i] != INFINITY) {
printf("%c(%2d):", G->Vertex[i], D[i]);
}
else printf("%c(∞):", G->Vertex[i]);
if (P[i][0] > 0) {
for (j = 1; j <= P[i][0]; j++) {
printf(" %c", P[i][j]);
if (j < P[i][0]) {
printf(" ->");
}
}
}
printf("%c\n", P[i][j]);
}
}