数据结构 最短路径之—迪杰斯特拉算法

本文介绍了一种使用迪杰斯特拉算法寻找无向图中最短路径的方法。通过初始化顶点距离并逐步迭代,该算法能够高效地确定任意两点间的最短路径。详细步骤包括初始化距离、选择最近节点及更新相邻节点距离。
#define MAXVEX 9
#define INFINITY 65535

typedef int PathMatrix[MAXVEX]			//用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVEX]		//用于存储到各点最短路径的权值和  比如V0到V2的权值是4 


void ShortestPath_DIJ(MGraph G, int V0, PathMatrix &P, ShortPathTable &D) //接口:输入的是无向图G,初始点VO,路径矩阵P,以及路径表格,
{

	int final[MAXVEX]; //final[v] = 1 表示已经求得顶点V0到Vw的最短路径。为1的话表明已经取得,为0的话表明还没有取得。


	//初始化数据 初始化数据用的是v0到其他各个结点的长度。
	for(v=0; v<G.numVertexes; v++)
	{
		final[v] = 0;			//全部顶点初始化为未找到的最短路径,所以初始化都为0
		(*D)[v] = G.arc[v0][v];		//将与v0点有联系的顶点加上权值(距离)。  在邻接矩阵中,从V0到V8的最大顶点数开始遍历。
		(*p)[V] = 0;                //初始化路径数组P为0;
	}
	(*D)[V0] = 0;                  //v0到v0的路径为0
	final[V0] = 1;                //V0到V0不需要求路径。

	//开始主循环,每次求得V0到某个V顶点的最短路径 这个循环分为两部分,根prim算法一样,先求出第一部分,然后进行纠正更新。
	for(v=1; v< G.numVertexes; v++) //从1开始的,从第一个顶点开始探讨 接着从下个结点开始。
	{
		min = INFINITY;

		//从D数组中找到最小的值。
		for(w=0; w<G.numVertexes; w++)
		{
			if(!final[w] && (*D)[w]<min) 
			{
				k = w;  //k存储的是距离当前结点距离最近的结点
				min = (*D)[w];
			}	
		}
	
	final[k] = 1;

	//修正当前最短路径以及距离  要求下一层的结点要小于上一个结点到其他结点的距离。
		for (w=0; w<G.numVertexes; w++)
		{
			if(!final[w] && min+G.arc[k][w] < [*D][w]) //当前的min+其他的。
			{
			    (*D)[w] = min + G.arc[k][w]  //修正当前路径长度; 利用前驱顶点和其他顶点的长度且和前面的长度累积比大小。
			    (*p)[w] = k;                 //存放前驱顶点。 前驱结点和这个结点相连接的权值之和为<(*D)[k]. 发现用到p没什么用!
			}
		}
	}

}

详情过程可以参考这个! 

https://wenku.baidu.com/view/6dc5c62486c24028915f804d2b160b4e767f810f

迪杰斯特拉(Dijkstra's Algorithm)是一种用于寻找有向图或无向图中最短路径的经典算法,通常用于单源最短路径问题。在C++中实现迪杰斯特拉,我们可以按照以下几个步骤: 1. **定义数据结构**: - 使用`std::priority_queue`来管理未处理的顶点及其距离估计。 - 定义一个辅助数组`dist`来记录每个顶点到已知源点的距离,初始时除了源点外全部设置为无穷大(通常用INT_MAX)。 - 可能还需要一个布尔数组`visited`来标记哪些顶点已被访问过。 2. **函数原型**: ```cpp void dijkstra(std::vector<std::pair<int, int>>& graph, int src, std::vector<int>& dist, std::vector<bool>& visited); ``` 其中`graph`是一个二维数组或邻接表,表示图的连接;`src`是源点的索引;`dist`和`visited`分别是距离数组和访问标志数组。 3. **核心算法流程**: - 将源点加入优先队列,初始距离设为0。 - 循环直到优先队列为空: a. 弹出优先队列中距离最小的未访问顶点u。 b. 更新其相邻顶点v的距离,如果通过u到v的距离小于当前已知距离,则更新`dist[v]`。 c. 标记顶点u为已访问。 - 结果会在`dist`数组中,`dist[i]`就是源点到顶点i的最短距离。 4. **示例代码片段**: ```cpp while(!pq.empty()) { int u = pq.top().second; // 获取下标 pq.pop(); visited[u] = true; // 更新相邻顶点v的距离 for (auto &edge : graph[u]) { int v = edge.first; int weight = edge.second; if (!visited[v] && dist[u] + weight < dist[v]) { dist[v] = dist[u] + weight; pq.push({dist[v], v}); } } } ``` 5. **输出结果**: 仅当`dist`数组完整计算完成后,可以遍历数组,获取从源点到所有其他顶点的最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值