Dijkstra 最短路径算法

Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

Dijkstra算法的基本思想是以起点为中心,不断的向外扩张,直到扩张到终点。同时Dijkstra最重要的定理是:如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。

1.      更新起点的权值。

2.      寻找起点附近权值最小的点。

3.      以最短的下一点为起点,更新权值。

4.      寻找下一点中权值最小的点。

5.      又更新权值(dist[j]=min{dist[j],dist[i]+matrix[i][j]})

6.      一直循环直到扩张到终点。





下面给出我写的Dijkstra 最短路径函数。输入参数分别是(邻接矩阵,起点,终点,用于保存路径权值的数值,邻接矩阵的下标最大值+1,保存路径的数组)

void Dijkstra(int ** const topo, int start, int end, int * path_weight, int topo_size, int * path)
{
	int i, j;
	int *mark;
	mark = (int *)malloc(sizeof(int) * topo_size);

	for (i = 0; i < topo_size; i++)
	{
		path_weight[i] = topo[start][i];
		if (topo[start][i] == Infinity)
		{
			path[i] = -1;
		}
		else
		{
			path[i] = start;
		}
		mark[i] = 0;
	}
	mark[start] = 1;
	path_weight[start] = 0;
	int next_start = start;
	for (i = 0; i < topo_size; i++)
	{
		//找到最小的权值
		int temp = Infinity;
		for (j = 0; j < topo_size; j++)
		{
			if (mark[j] == 0 && path_weight[j] < temp)
			{
				temp = path_weight[j];
				next_start = j;
			}
		}
		if (next_start == end && next_start == start)
			break;
		mark[next_start] = 1;
		for (j = 0; j < topo_size; j++)
		{
			if (mark[j] == 0 && topo[next_start][j] != Infinity)
			{
				//更新每一步的权值
				if (path_weight[j] > (path_weight[next_start] + topo[next_start][j]) )
				{
					path_weight[j] = path_weight[next_start] + topo[next_start][j];
					path[j] = next_start;
				}
			}
		}
	}
	free(mark);
	printf("源点%d到顶点%d路径总长度: %d \n%d",start, end, path_weight[end], end);
	find(path, end);
	printf("\n");
}

参考链接:

http://blog.csdn.net/longshengguoji/article/details/10756003/

http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html

http://blog.163.com/cindy_19810217/blog/static/20105911820131019114612133/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值