图的邻接矩阵--最短路径-Dijkstra算法

本文详细介绍了Dijkstra算法,通过实例演示如何使用邻接矩阵表示图,以及如何利用该算法寻找从源点v到其他所有顶点的最短路径。通过源点v的初始化和不断缩小待处理顶点集合,逐步更新最短路径长度,直至遍历完所有顶点。
摘要由CSDN通过智能技术生成

图的邻接矩阵–最短路径-Dijkstra算法
//代码附有详细注释
完整代码在文章最后。

常量,用于表示图中的无穷(max)和顶点个数(n)
不同的图对应不同的顶点个数。

#define max 1000
#define n 5

方便理解的别名

typedef int Graph[n][n];   //图
//typedef <元素类型关键字><数组类型名>[<常量表达式1>][<常量表达式2>]
typedef int vertex;   //顶点 

算法核心
G为已存在的图,v表示源点,dist数组用于辅助查找搜索

void shortp(Graph G, vertex v, int dist[n])
//源点v
//dist[n]表示当前所找到的从源点v到终点Vi的最短路径长度
{
	int i, wmin, u, S[n];
	//wmin代表一次搜索过程中最小值,u代表其最小值指向的顶点
	int num=1;
	for (i=0; i<n; i++)//数组dist及集合S赋初值
	{
		dist[i]=G[v][i];
		S[i]=0;          
	}
	S[v]=1;              //把顶点v加入集合S中,1表示在集合S当中,0表示不在集合S中
	do{
		wmin=max; 
		u=v;
		for(i=0; i<n; i++)  //选择顶点u
		{
			if (S[i] == 0)  //不在集合S中的顶点
			{
				if (dist[i] < wmin)   //找到最小值及其顶点
				{
					u=i;
					wmin=dist[i];
				}
			}
		}
		S[u]=1;    //把找到的顶点加入到集合S中
		for (i=0; i<n; i++) 
		{
			if (S[i] == 0)  //不在集合S中的顶点
			{
				if (dist[u]+G[u][i] < dist[i])  //u为最小值指向的顶点,dist[u]+G[u][i]表示从源点v0先到顶点u再到其他顶点的路径,dist[i]表示从源点v0直接到其他顶点的路径
					dist[i]=dist[u]+G[u][i];   //取两者最小的作为源点v0直接到其他顶点的路径
			}
		}
		num++;
	}while (num != n-1);
}

主函数用于测验,图设置为有向网图
有向网图G

void main()
{ 
	Graph G={
		{    0,   10,10000,   30,  100},
		{10000,    0,   50,10000,10000},
		{10000,10000,    0,10000,   10},
		{10000,10000,   20,    0,   60},
		{10000,10000,10000,10000,    0}}; 
	vertex v=0; //源点v
	int dist[n], i, j;
	printf("please input weight of Graph ( 10000 is NaN ):\n"); 
	for(i=0; i<n; i++)
	{
		for(j=0; j<n; j++)	printf("%5d  ", G[i][j]);
		printf("\n");
	}
	printf("\n");
	shortp(G, v, dist);
	for (i=0; i<n; i++) 
		if (i != v)
			printf("the shortest path of v[%d]->[%d] is:%d\n",v,i,dist[i]);
	printf("\n");
}

最后,如果觉得这篇博客能帮助到你,请点个小小的支持一下我(收藏也行呀,嘻嘻),这是我继续更新的动力呀,关注我可以得到第一时间的更新,更加快人一步哦。
如果有问题请在评论区留言,一起交流进步。
附完整代码

#include "stdio.h"
#include "stdlib.h"

#define max 1000
#define n 5

typedef int Graph[n][n];   //图
//typedef <元素类型关键字><数组类型名>[<常量表达式1>][<常量表达式2>]
typedef int vertex;   //顶点 

void shortp(Graph G, vertex v, int dist[n])
//源点v
//dist[n]表示当前所找到的从源点v到终点Vi的最短路径长度
{
	int i, wmin, u, S[n];
	//wmin代表一次搜索过程中最小值,u代表其最小值指向的顶点
	int num=1;
	for (i=0; i<n; i++)//数组dist及集合S赋初值
	{
		dist[i]=G[v][i];
		S[i]=0;          
	}
	S[v]=1;              //把顶点v加入集合S中,1表示在集合S当中,0表示不在集合S中
	do{
		wmin=max; 
		u=v;
		for(i=0; i<n; i++)  //选择顶点u
		{
			if (S[i] == 0)  //不在集合S中的顶点
			{
				if (dist[i] < wmin)   //找到最小值及其顶点
				{
					u=i;
					wmin=dist[i];
				}
			}
		}
		S[u]=1;    //把找到的顶点加入到集合S中
		for (i=0; i<n; i++) 
		{
			if (S[i] == 0)  //不在集合S中的顶点
			{
				if (dist[u]+G[u][i] < dist[i])  //u为最小值指向的顶点,dist[u]+G[u][i]表示从源点v0先到顶点u再到其他顶点的路径,dist[i]表示从源点v0直接到其他顶点的路径
					dist[i]=dist[u]+G[u][i];   //取两者最小的作为源点v0直接到其他顶点的路径
			}
		}
		num++;
	}while (num != n-1);
}

void main()
{ 
	Graph G={
		{    0,   10,10000,   30,  100},
		{10000,    0,   50,10000,10000},
		{10000,10000,    0,10000,   10},
		{10000,10000,   20,    0,   60},
		{10000,10000,10000,10000,    0}}; 
	vertex v=0; //源点v
	int dist[n], i, j;
	printf("please input weight of Graph ( 10000 is NaN ):\n"); 
	for(i=0; i<n; i++)
	{
		for(j=0; j<n; j++)	printf("%5d  ", G[i][j]);
		printf("\n");
	}
	printf("\n");
	shortp(G, v, dist);
	for (i=0; i<n; i++) 
		if (i != v)
			printf("the shortest path of v[%d]->[%d] is:%d\n",v,i,dist[i]);
	printf("\n");
	system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

“翎羽”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值