C++版本迪杰斯特拉(Dijkstra)算法原理讲解及代码实现

C++版本迪杰斯特拉(Dijkstra)算法原理讲解及代码实现


迪杰斯特拉算法图

/*!
* Copyright (c) 2020,ZYF.
* All Rights Reserved.
*
* \file Dijkstra.cpp
* \brief 迪杰斯特拉算法
*
* \author ZYF
* \date 2020/6/30 18:30:42
* \version 1.0.0
*/

#include <iostream>

/** 邻接矩阵行列的最大数 */
const int g_nMaxNumber = 100;

/** 最大整数(代表无穷大) */
const int g_nMaxInt = 999999;

/*!
* \brief 迪杰斯特拉算法
* \param nNodes : int 顶点总数
* \param nV : int 源点
* \param pDist : int * 当前点到源点的最短距离
* \param pPrev : int * 当前点的前一节点
* \param matrixDistance : int 两点间的距离(邻接矩阵)
* \returns void :
* \throws <exception class>
* \remarks
* \see
*/
void Dijkstra(int nNodes, int nV, int* pDist, int* pPrev, int matrixDistance[g_nMaxNumber][g_nMaxNumber])
{
   
	/*
	算法描述:
		迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。
		是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。
		迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

	算法逻辑:
		1. 初始化两个集合,S集合和V集合。
			S集合初始只有源顶点即顶点A,
			V集合初始为除了源顶点以外的其他所有顶点,
			dist字典值都为-1;
			紧接着,根据邻接矩阵,找出与A存在边的顶点list,
			遍历list,依次更新dist字典(比如list={B,C},则依次更新字典键为B,C 的距离值),
			求出与 A 距离最近的顶点,并从V集合中移除到S集合中;
		2. 抓出S集合的最后一个元素,根据邻接矩阵,找出V集合中与之存在边的顶点list,
		遍历list,求出与之距离最小的顶点,并从V集合中移除到S集合中。
		3 dist更新,分情况讨论,
			3.1如果遍历到的顶点不是与之最小的顶点,则直接更新dist字典,比如list={D,E},则依次更新字典键为D,E的距离值,
			3.2如果遍历到的顶点是与之最小的顶点,则需要判断dist[此顶点]与当前的距离,如果后者小,才更新dist[此顶点],否则不更新。
		4. 重复2和3,直到V集合元素为空为止。
	*/

	bool bArr[g_nMaxNumber];//判断是否放到集合S中(true:已使用;false:未使用)标记数组,标记顶点是否已经被选择过
	for (int i = 1; i <= nNodes; i++)
	{
   
		pDist[i] = matrixDistance[nV][i];
		bArr[i] = false;

		if (pDist[i] == g_nMaxInt)
			pPrev[i] = 0;
		else
			pPrev[i] = nV;
	}

	pDist[nV] = 0;
	bArr[nV] = true;

	//依次将未放入S集合的结点中,取pDist[]最小值的结点,放入结合S中
	//一旦S包含了所有V中顶点,pDist就记录了从源点到所有其他顶点之间的最短路径长度
	//注意是从第二个节点开始,第一个为源点

	int nTmp = 0;//临时,找最小距离使用
	int nIndex = 0;//最小距离的索引
	for (int i = 2; i <= nNodes; i++)
	{
   
		nTmp = g_nMaxInt;
		nIndex = nV;

		//找出当前未使用的点j的最短距离pDist[j]
		for (
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhangyanfeng1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值