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 (