《数据结构(C语言版)第二版》第六章-图(6.6 图的应用——6.6.2 最短路径【有向网】)

最短路径的对象是(带权)有向网。

6.6.2.1 从某个源点到其余各顶点的最短路径

迪杰斯特拉算法

C语言常见问题——数组初始化的四种方法 —— 易水卷长空

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

#define MaxInt 32767
#define MVNum 100

typedef char VerTexType;
typedef int ArcType;


bool S[MVNum]; //记录从源点v0到终点vi是否已被确定最短路径长度,true表示确定,false表示尚未确定。
ArcType D[MVNum]; //记录从源点v0到终点vi的当前最短路径长度。
int Path[MVNum]; //记录从源点v0到终点vi的当前最短路径上vi的直接前驱顶点序号(下标)。
//这三个数组中的每个下标,与G.vexs中各顶点的下标是一致的

int reverse[MVNum];  //未对reverse数组进行初始化时,需将其定义为全局变量

typedef struct
{
   
   
	VerTexType vexs[MVNum];
	ArcType arcs[MVNum][MVNum];
	int vexnum;
	int arcnum;
}AMGraph;

void CreateAMGraph(AMGraph& G);
int LocateVex(AMGraph G, VerTexType v);
void printAMGraph(AMGraph G);
void ShortestPath(AMGraph G, int v0);
void printPath(AMGraph G, int v0);

int main()
{
   
   
	AMGraph G = {
   
    {
   
   0},{
   
   0},0,0 };
	int i = 0;
	CreateAMGraph(G);
	printAMGraph(G);

	printf("\n");
	ShortestPath(G, 0);
	printPath(G, 0);

	return 0;
}


//创建带权有向网的邻接矩阵
void CreateAMGraph(AMGraph& G)
{
   
   
	int i = 0;
	int j = 0;
	int k = 0;
	VerTexType v1 = '\0';
	VerTexType v2 = '\0';
	ArcType w = 0;

	printf("请输入总顶点数:");
	scanf_s(" %d", &G.vexnum);

	printf("请输入总边数:");
	scanf_s(" %d", &G.arcnum);

	for (i = 0; i < G.vexnum; i++)
	{
   
   
		printf("请输入第%d个顶点的值:", i + 1);
		scanf_s(" %c", &G.vexs[i]);

		for (j = 0; j < G.vexnum; j++)
		{
   
   
			G.arcs[i][j] = MaxInt;
		}
	}

	for (k = 0; k < G.arcnum; k++)
	{
   
   
		printf("请输入第%d条边的两个顶点:", k + 1);
		scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));

		printf("请输入第%d条边的权值:", k + 1);
		scanf_s(" %d", &w);

		i = LocateVex(G, v1);
		j = LocateVex(G, v2);

		G.arcs[i][j] = w;
	}
}

int LocateVex(AMGraph G, VerTexType v)
{
   
   
	int i = 0;

	for (i = 0; i < G.vexnum && (G.vexs[i] != v); i++)
	{
   
   
		;
	}

	return i;
}

void printAMGraph(AMGraph G)
{
   
   
	int i = 0;
	int j = 0;

	printf("各顶点值为:");
	for (i = 0; i < G.vexnum; i++)
	{
   
   
		printf("%c ", G.vexs[i]);
	}

	printf("\n邻接矩阵为:\n");
	for (i = 0; i < G.vexnum; i++)
	{
   
   
		for (j = 0; j < G.vexnum; j++)
		{
   
   
			if (G.arcs[i][j] == MaxInt)
			{
   
   
				printf("%d   ", G.arcs[i][j]);
			}
			else if (G.arcs[i][j] > 9)
			{
   
   
				printf("%d      ", G.arcs[i][j]);
			}
			else
			{
   
   
				printf("%d       ", G.arcs[i][j]);
			}
		}

		printf("\n");
	}
}

//用Dijkstra算法求有向网G的下标为vO的顶点到其余顶点的最短路径
void ShortestPath(AMGraph G, int v0)
{
   
   
	int n = G.vexnum;
	int v = 0;
	int i = 0;
	int min = 0;
	int w = 0;

	for (v = 0; v < n; ++v)
	{
   
   
		if (v != v0)
		{
   
   
			S[v] = false;
			D[v] = G.arcs[v0][v];

			if (D[v] < MaxInt)
			{
   
   
				Path[v] = v0;
			}
			else
			{
   
   
				Path[v] = -1;
			}
		}
		else
		{
   
   
			S[v] = true;
			D[v] = 0;
			Path[v] = -1;
		}
	}

	for (i = 1; i < n; i++)
	{
   
   
		//在未被确定最短路径长度的顶点中(S[w]为false),寻找各顶点最短路径长度D[w]的最小值min
		min = MaxInt;
		for (w = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值