Dijkstra算法代码实现

题目:单源最短路径问题的问题提出是,计算带权有向图G =(V, E)中一个点(源点)到其余各顶点的最短路径长度,如下图所示。设源点为顶点1,采用Dijkstra算法求下图中源V0为到其余各顶点的最短路径。

 代码实现:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define INF 100//距离无穷大,定义100是怕栈溢出
#define MAX_SIZE 100//数组容量
int dist[MAX_SIZE];//距离数组
int path[MAX_SIZE];//路径数组
int visited[MAX_SIZE];//访问数组 未访问0 已访问1
struct Graph
{
	int vertex[MAX_SIZE];//顶点数组
	int arc[MAX_SIZE][MAX_SIZE];//边数组
	int vertexnum, arcnum;//顶点和边的个数
};
void GraphCreate(struct Graph* graph)//用邻接矩阵表示图,初始化和创建
{
	for (int i = 1; i <= graph->vertexnum; i++)//初始化
		for (int j = 1; j <= graph->vertexnum; j++)
			graph->arc[i][j] = INF;//这里初始化为无穷大是方便初始化路径数组
	int a = 0, b = 0, w = 0;//我有初始化的好习惯~
	for (int i = 1; i <= graph->arcnum; i++)//创建
	{
		printf("请输入有边依附的两个顶点的编号以及权重:\n");
		scanf("%d%d%d", &a, &b, &w);
		graph->arc[a][b] = graph->arc[b][a] = w;
	}
}
void Dijsktra(struct Graph* graph, int from, int to)
{
	for (int i = 1; i <= graph->vertexnum; i++)//初始化数组
	{
		dist[i] = graph->arc[from][i];//距离初始化为源点到其他各顶点的距离
		visited[i] = 0;//默认都没有访问过
	}
	for (int i = 1; i <= graph->vertexnum; i++)
	{
		if (dist[i] == INF)
			path[i] = -1;//如果没有边连接就初始化为-1
		else
			path[i] = from;
	}
	for (int i = 1; i < graph->vertexnum; i++)//除源点外去最小的路径
	{	
		int min = 100; 
		int pos = -1;//记录找到的下标
		for (int j = 1; j <= graph->vertexnum; j++)
		{
			if (!visited[j] && dist[j] < min)//如果未访问并且有更小的,那么更新
			{
				min = dist[j]; 
				pos = j;
			}
		}
		visited[pos] = 1;//找到了就标记已经访问
		for (int j = 1; j <= graph->vertexnum; j++)//更新dist数组
		{
			if (!visited[j] && dist[pos] + graph->arc[pos][j] < dist[j])
			{   //dist[pos]是前面一个结点到该结点的距离,are[pos][j]是该结点到下一个结点的距离
				//dist[i]是前面一个结点到下一个结点的距离 可以理解为两条折线和一条直线的距离去比较长短
				dist[j] = dist[pos] + graph->arc[pos][j];
				path[j] = pos;
			}
		}
	}
	printf("最短路径为:%d\n",dist[to]);
}
void PrintPath(int path[], int from, int to)//打印路径 我用递归感觉更方便,csdn好多堆栈来写!!
{
	if (path[to] != from)
	{
		PrintPath(path, from, path[to]);
		printf("%d->", path[to]);
	}
	else
		printf("%d->", path[to]);
}
int main()
{
	struct Graph graph; 
	printf("请分别输入顶点和边的个数:\n");
	scanf("%d%d",&graph.vertexnum, &graph.arcnum);
	GraphCreate(&graph);
	int from = 0,to = 0;
	printf("请输入起点和终点:\n");
	scanf("%d%d", &from, &to);
	Dijsktra(&graph, from, to);
	PrintPath(path, from, to);
	printf("%d", to);  //因为路径数组里面只有路径,没有终点!!
	return 0;
}

 运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jacob~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值