数据结构之图的最短路径(Dijkstra & Floyd)【1】

前言

计算图的最短路径,比较常见的算法有两种,一种是计算单源最短路径的Dijkstra算法,一种是计算任意两个点对最短路径的Floyd算法。这篇文章中主要的内容是Dijkstra算法的原理和实现。

一、原理

1.算法特点:

       个人认为,Dijkstra算法的原理其实就是广度优先搜索,即逐步查找整张图,不管输入节点的位置情况,最后得到的也是所有点到源点的最小路径情况。

2.算法描述:

        Dijkstra算法从用户输入的某个节点编号(a)开始,然后查找出与a相连通且权值最小的点,将其加入已确定路径点的集合 (T)中。之后每次循环,查找出从源点出发,经过T中新加入的点,再到当前点,路径权值是否有变化。若有变化,则更新路径信息。之后再重复循环,找出未确定路径点集合中(没有加入集合T的点即为未确定路径点),权值最小的那个,重复上述循环直至所有点都加入集合 T 中。

3.与Prim算法比较:

Dijkstra算法 和 Prim算法的原理都是一样是 广度优先搜索,只不过前者每次循环更新的是其余点到源点的路径信息(路径权值总和最小),后者更新的是总体权值总和最小。它们都是每次加入一个点,从某个确定点开始,逐步展开至整张图。

二、代码

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

#define MaxDis 65536
struct Dis {
	string path;       //源点到此点的目前最短路径(循环更新直至最后不变)
	int value;          //最短路径权值(最小权值)
	bool visit;        //是否已经确定了最短路径
	Dis() {
		visit = false;
		value = 0;
		path = "";
	}
};

struct Matrix
{
	int iVexNum;
	int iEdgeNum;
	int** iArcs;
};

void Dijkstra(Matrix g, int begin)
{
	Dis* dis = new Dis[g.iVexNum];     //保存路径信息和权值信息
	int i;
	int count=0;                   //路径已确定的点的数量
	for(i=1;i<g.iVexNum;i++)       //初始化,所有点到begin点的距离信息
	{
		dis[i].value = g.iArcs[begin][i];
		dis[i].path = std::to_string(begin) +","+ std::to_string(i);
	}

	dis[begin].value = 0;     //将begin点加入已确定路径的点的集合
	dis[begin].visit = true;
	
	while (count != g.iVexNum)  //循环直至所有点都加入已确定集合
	{
		int iTemp;           //临时变量,保存当前value值最小的点的编号
		int min = MaxDis;     //开始时Min值设为最大

		for (i = 0; i < g.iVexNum; i++)    //循环找到当前最小的权值点
		{
			if (!dis[i].visit&&dis[i].value < min)
			{
				min = dis[i].value;
				iTemp = i;
			}
		}

		dis[iTemp].visit = true;  //每轮循环结束后的最小权值路径对应的点,就可以加入已确定路径集合中
		count++;
		for (i = 0; i < g.iVexNum; i++)
		{
			if (!dis[i].visit && g.iArcs[iTemp][i] != MaxDis 
                            && (dis[iTemp].value + g.iArcs[iTemp][i] < dis[i].value))
			{ 
				//如果加入新的点后,有其他的点变成可达或者从begin前往的路径权值变小,那么就更新
				dis[i].path = dis[iTemp].path + "," + std::to_string(i);
				dis[i].value = dis[iTemp].value + g.iArcs[iTemp][i];
			}
		}
	}
}

总结

代码好像也没有什么要总结的地方,可能,查找一组数据中最小值时,先将临时保存最小值的变量 min 设为最大值 65536 之类的最大值算是一个小技巧….吧?我这也是强行总结了。。

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/tulensa/article/details/79414191
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞