数据结构(13)---图(最短路径----迪杰斯特拉算法)

最端路径:对于网图来说,最短路径,是指两个顶点之间经过的边上权值之和最少的路径,并且称路径上的第一个顶点时源点,最后一个顶点是终点。算法主要有两种:迪杰斯特拉算法,弗洛伊德算法。

 

使用以上网图,分别对迪杰斯特拉算法和弗洛伊德算法进行说明。

迪杰斯特拉算法:

迪杰斯特拉算法采用了贪心的策略,可以求出顶点到图中每个点的最短路径,时间复杂度为:n^2。

申请shortesPath数组和fromVertex数组。

shortesPath数组存储从0顶点到其他顶点的最短距离。

fromVertex数组存储从0顶点到其他顶点经过了那些点。

(1)分别对shortesPath数组和fromVertex数组进行初始化(“#”不可达,红色表示该点被访问)。

 012345
shortesPath09424##
fromVertex000000

 表达的含义为从0号点开始,经过0号点到达各个点(数据下表就表示各个点)的距离。(就是从0号点开始到各个点的距离)

(2)在shportPath数组中选择一个最小的点。因为4的值最小,所以选取的点为2号顶点。

(3)更新shortesPath数组的内容。计算比较从0直接到各个顶点的距离是否大于从0开始经过2号点再到达各个顶点的距离。和2直接相连的顶点有两个为3号顶点和5号顶点。因为24>4+e(2,3)=16,即从0号顶点直接到3顶点的权值(24)大于从0号顶点经过2号顶点到3号顶点的权值(16),将3号顶点的24修改为16。同理,#>4+e(2,5)=21,将5号顶点的#修改为21。并将fromVertex数组的3,5的内容修改为2。

更新后的表:

 012345
shortesPath09416#21
fromVertex000202

再按照(2)的方法从shportPath数组(未被访问的点)中选择一个最小的点。因为9最小所以选择1号顶点。按照(3)的方法更新shortesPath数组的内容。

和1号顶点直接相连的顶点有3号顶点和4号顶点,又因为16>9+1=10,#>9+e(1,4)=11,

将3号顶点的值修改为10,4号顶点的值修改为11。将fromVertex数组的4的内容修改为1。

 012345
shortesPath094101121
fromVertex000112

重复(2)(3),直到所有点都被访问。

选取3号顶点,和3号顶点直接相连的顶点有0,1,2,4,5。

10+e(3,0)=10+24=34>0

10+e(3,1)=10+1=11>9

10+e(3,2)=10+12=22>4

10+e(3,4)=10+4=14>11

10+e(3,5)=10+4=14<21

 012345
shortesPath094101114
fromVertex0001·13

选取4号顶点,和4号顶点直接相连的顶点1,3,5。

11+e(4,1)=11+2=13>9

11+e(4,3)=11+4=15>11

11+e(4,5)=11+9=20>14

 012345
shortesPath0941011

14

fromVertex000113

选取5号顶点,和5号顶点直接相连的顶点2,3,4。

14+e(5,2)=14+17=31>4

14+e(5,3)=14+4=18>10

14+e(5,4)=14+9=23>11

 

 012345
shortesPath0941011

14

 

fromVertex000113

所有顶点被访问,shortesPath数组中存储的就是从0号顶点开始到各个顶点的最短路径的权值。

结合fromVertex数组可以得出最短路径。

最短路径权值
0--->19
0--->24
0---->1--->3  10
0---->1----->4    11
0----->1--->3---->5 14
//迪杰斯特拉算法
void Dijkstra(MGraph pGraph)
{
	//记录最短路径的值的数组
	int shortesPath[MAXVEX] ;
	int visitVertex[MAXVEX];
	//记录使用过顶点的集合
	int fromVertex[MAXVEX];
	for (int i= 0; i < pGraph.vertexNum; ++i)
	{
		shortesPath[i] = pGraph.graphEdge[0][i];
		fromVertex[i] = 0;
		visitVertex[i] = 0;
	}
	visitVertex[0] = 1;
	for (int i = 1; i < pGraph.vertexNum; ++i)
	{
		int minWight = MINFINITE;
		int min = -1;
		for (int j = 1; j < pGraph.vertexNum; ++j)
		{
			if (visitVertex[j] == 0 && minWight>shortesPath[j])
			{
				minWight = shortesPath[j];
				min = j;
			}
		}
		visitVertex[min] = 1;
		for (int j = 1; j < pGraph.vertexNum; ++j)
		{
			if (pGraph.graphEdge[min][j] != MINFINITE)
			{
				if (shortesPath[min] + pGraph.graphEdge[min][j] < shortesPath[j])
				{
					shortesPath[j] = shortesPath[min] + pGraph.graphEdge[min][j];
					fromVertex[j] = min;
				}
			}
		}
	}
	printf("最短路径权值:\n");
	for (int i = 0; i < pGraph.vertexNum; ++i)
	{
		printf("%-3d,",shortesPath[i]);
	}
	printf("\n经过顶点:\n");
	for (int i = 0; i < pGraph.vertexNum; ++i)
	{
		printf("%-3d,", fromVertex[i]);
	}
	printf("\n");
	for (int i = 1; i < pGraph.vertexNum; ++i)
	{
		int j = i;
		printf("%c--->",pGraph.graphVertex[i].data);
		while (fromVertex[j] != 0)
		{
			printf("%c---->", pGraph.graphVertex[fromVertex[j]].data);
			j = fromVertex[j];
		}
		printf("%c\n", pGraph.graphVertex[0].data);
	}
}

 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值