迪杰斯特拉算法

最短路径问题是指:从在带权图的某一顶点出发,找出一条通向另一顶点的最短路径。这里仅考虑,非负权值的单源路径最短

迪杰斯特拉算法,按路径的递增次序,逐步产生最短路径的算法。首先求出长度最短的一条最短路径,然后参照它求出长度次短的一条最短路径,依次类推,直到从顶点v到其他各顶点的最短路径全部求出为止。

迪杰斯特拉算法

迪杰斯特拉是位计算机大神,大师级人物.

该算法的思想:设定一个最短路径顶点集合,用于标记,每次找到当前最短路径,然后动态查找改变,下一个最短路径次序。

/*
Dijkstra算法:(i,j,k)
1、声明一个访问过结点集,用于标示每次是否被访问,初始化为假,对应已访问顶点集为空。
2、v=0;设置path数组,当此结点未访问,且小于最大值,设置路径为初始结点,
然后初始化当前最短路径数组dest,然后把初始结点设置为已访问过。
3、循环处理:
*/

void Dijkstra(int weight[5][5],int v,int dest[],int path[])

{

	int road[5];

	int i,j ,k;

	bool shortset[5];

	int min;		//记录当前最小,选择一个结点和其他结点连接的最短路

	int u;			//用于记录是否经过u达到最短路径

	int w;			//辅助

	for(i=0;i<5;i++)

	{

		dest[i]=weight[v][i];

		shortset[i]=false;

		if(dest[i]<MaxValue)	//如果有路,则将path数组设置为初始结点

			path[i]=v;

		else

			path[i]=-1;



	}



	shortset[v]=true;

	dest[v]=0;



	for(i=0;i<4;i++)	//循环处理到n-1个结点,里面的操作可以把最后一个结点加入到已访问集中

	{

		min=MaxValue;u=v;	//最新访问的



		for(j=0;j<5;j++)

			if(shortset[j]==false&&dest[j]<min)

			{

				u=j;		//j即为选出的最短路径结点

				min=dest[j];	

			}

		//将此结点加入到最短路径集中

			shortset[u]=true;

			

		for(k=0;k<5;k++)	//动态测试模块:只修改路径,不访问结点

		{

			w=weight[u][k];	//经过u到达其他结点

			if(shortset[k]==false&&w<MaxValue&&dest[u]+w<dest[k])

			{

				//缩短了路径,则把该结点加入到最短路径集中

				dest[k]=dest[u]+w;

		//		shortset[k]=true;	//典型错误:

				path[k]=u;			//类似并查集的索引

			}

		}

	}



	//测试

	cout<<"最短路径数组:"<<endl;

	for(i=0;i<5;i++)

	{

		cout<<dest[i]<<" ";

	}

	cout<<endl;

	cout<<"最短路径序列数组:"<<endl;

	for(i=0;i<5;i++)

	{

		cout<<path[i]<<" ";	

	}

	cout<<endl;

	cout<<"访问控制数组:"<<endl;

	for(i=0;i<5;i++)

	{

		cout<<shortset[i]<<" ";	

	}

	cout<<endl;



	//输出到各顶点的最短路径和最短路径序列

	cout<<"-------测试结果---------------"<<endl;

	for(i=1;i<5;i++)

	{

		cout<<"顶点0到顶点"<<i<<"的最短路径长度为:"<<dest[i]<<endl;

		cout<<"最短路径序列为:"<<endl;

		

		//处理类似数组下标作为索引的数据结构的标准代码

		k=0;

		int j=i;

		while(j>0)

		{

		//	road[k++]=path[j--]; 有纰漏

			road[k++]=j;

			j=path[j];		//顺次调用

		}

		while(k>0)

			cout<<road[--k]<<" ";	//k使用完还加1了,所以应该使用--k

		cout<<endl;

		cout<<endl;

	}



}

主程序:

#define MaxValue 1999999



int _tmain(int argc, _TCHAR* argv[])

{

	int weight[5][5]=				//用矩阵表示有向带权图

	{

		{0,10,MaxValue,30,100},

		{MaxValue,0,50,MaxValue,MaxValue},

		{MaxValue,MaxValue,0,MaxValue,10},

		{MaxValue,MaxValue,20,0,60},

		{MaxValue,MaxValue,MaxValue,MaxValue,0}

	};

	int dest[5];		//记录起始点到各个点的最短路径

	int path[5];		//记录当该顶点经过的顶点次序

	for(int i=0;i<5;i++)	//都初始化为0

	{

		dest[i]=0;

		path[i]=0;

	}

	//经验:典型,重点,难点,勿钻研生僻点

	cout<<"------最短路径之Dijkstra算法------"<<endl;

	void Dijkstra(int weight[5][5],int v,int dest[],int path[]);



	

	//测试

	Dijkstra(weight,0,dest,path);

	



	return 0;

}

测试结果:

------最短路径之Dijkstra算法------
最短路径数组:
0 10 50 30 60
最短路径序列数组:
0 0 3 0 2
访问控制数组:
1 1 1 1 1
-------测试结果---------------
顶点0到顶点1的最短路径长度为:10
最短路径序列为:
1

顶点0到顶点2的最短路径长度为:50
最短路径序列为:
3 2

顶点0到顶点3的最短路径长度为:30
最短路径序列为:
3

顶点0到顶点4的最短路径长度为:60
最短路径序列为:
3 2 4

请按任意键继续. . .

你可能感兴趣的:(算法)