图——最短路径Dijkstra算法

Dijkatra算法解决了从某个源点到其余各顶点的最短路径问题。时间复杂度为O(n^{2})。如果我们还需要知道v3到v5、v1到v7这样任一顶点到其余其他顶点的最短距离,可以对每个顶点当作源点运行一次Dijkstra算法,等于在原有算法的基础上,再来一次循环,此时整个算法的时间复杂度就成了O(n^{3})。Floyd算法就是求所有顶点到所有顶点的算法,算法非常简洁优雅,能让人感觉到智慧的无穷魅力,其时间复杂度就是O(n^{3})

Dijkatra算法所使用到的三个额外数组:

visited[MaxVex]标记数组,visited[w]=1表示已求得V0至Vw的最短路径,0表示还未求得
Distance[MaxVex],用于存储其他顶点到V0的最短距离
pre[MaxVex],用于记录从V0到该顶点的最短路径中,该下标的顶点的前驱顶点下标,通过pre数组可以找到任意顶点到V0的最短路径所经过哪些顶点

Dijkatra算法和Prim算法的相似点与不同点:

两个算法的代码极其相似。Dijkatra算法思想是全局最短,目的是计算出最短路径;Prim算法是局部连接到生成树的权值最小,目的是得到生成树。Prim算法用到两个数组

lowcost[MaxVex],记录未加入生成树的顶点到生成树的最小权值距离min_cost,已加入生成树的权值lowcost=0

adjvex[MaxVex],记录未加入生成树的顶点与生成树相连的最小权值距离的顶点下标

比Dijkatra算法少使用一个visited[MaxVex]标记数组,这是因为Prim算法可以通过lowcost=0标记该顶点已经加入生成树了,不用记录下权值距离,这是因为Prim算法强调最后得到一颗生成树,而Dijkatra算法强调计算出最短路径和最短距离,需要Distance数组记录最短距离。

#include
using namespace std;
#define MaxVex 100  //定义最大顶点数
#define Inf 65535  //定义无穷大
typedef char VertexType;  //定义顶点数据类型
typedef int EdgeType;  //定义边上权值数据类型
int visited[MaxVex];  //标记数组,visited[w]=1表示已求得V0至Vw的最短路径,0表示还未求得
int Distance[MaxVex];  //用于存储其他顶点到V0的最短距离
int pre[MaxVex];  //用于记录从V0到该顶点的最短路径中,该下标的顶点的前驱顶点下标,通过pre数组可以找到任意顶点到V0的最短路径所经过哪些顶点
//邻接矩阵存储图的结构
typedef struct Graph
{
	VertexType vex[MaxVex];  //一维数组存储顶点信息
	EdgeType arc[MaxVex][MaxVex];  //二维数组存储边的权值信息,也就是邻接矩阵
	int numVex,numArc;  //记录图中当前顶点数、边数
}MatrixGraph;
//建立无向网图的邻接矩阵表示
void CreateMatrixGraph(MatrixGraph *G)
{
	int i,j,k,weight;
	//输入顶点数和边数
	cin>>G->numVex>>G->numArc;
	//输入顶点信息,建立顶点表
	for(i=0;inumVex;i++)
		cin>>G->vex[i];
	//初始化邻接矩阵
	for(i=0;inumVex;i++)
		for(j=0;jnumVex;j++)
			G->arc[i][j]=Inf;
	//输入边信息,建立邻接矩阵
	for(k=0;knumArc;k++)
	{
		cin>>i>>j>>weight;
		G->arc[i][j]=weight;
		G->arc[j][i]=G->arc[i][j];  //无向图,矩阵对称
	}
}
void Dijkstra(MatrixGraph G,int v0)
{
	int i,j,min_vex,min_Distance;
	//初始化visited、Distance、pre三个数组
	for(i=0;i

 

你可能感兴趣的:(数据结构与算法分析)