实例讲解Dijkstra算法,代码实现求最短路径并记录路径
Dijkstra算法文字简述:Dijkstra算法算是贪心思想实现的。首先把起点到所有点的距离中找到最短的,然后松弛一次再找出最短的,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。松弛操作:松弛即更新。把刚刚找到的距离最短的点作为中转站再遍历一遍看看会不会更近,如果更近了就更新距离。算法流程图实例演示Dijkstra算法例:求1到6的最短路径1.将起点放入容器:容器A:1(0);括号内
Dijkstra算法
文字简述:Dijkstra算法算是贪心思想实现的。首先把起点到所有点的距离中找到最短的,然后松弛一次再找出最短的,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。
松弛操作:松弛即更新。把刚刚找到的距离最短的点作为中转站再遍历一遍看看会不会更近,如果更近了就更新距离。
算法流程图
实例演示Dijkstra算法
例:求1到每个点的最短路径
1.将起点放入容器:容器A:1(0);括号内表示最短路径
找出与 容器A 内的点距离最小的点:2;
注意:找出的点不能是容器A内的
将2放入已确定最短路径点的集合中,更新容器A:1(0),2(1);
2.找出与 容器A 内的点距离最小的点(此时容器A内有两个点):4
将4放入容器A中,更新容器:1(0),2(1),4(4);
3.找出与 容器A 内的点距离最小的点(此时容器A内有三个点):3
将4放入容器A中,更新容器A:1(0),2(1),4(4),3(8);
4.找出与 容器A 内的点距离最小的点(此时容器A内有四个点):5
将5放入容器A中,更新容器A:1(0),2(1),4(4),3(8),5(13);
5.找出与 容器A 内的点距离最小的点(此时容器A内有五个点):6
将6放入容器A中,更新容器A:1(0),2(1),4(4),3(8),5(13),6(17);
求最短路径并记录路径代码如下:
程序结果截图:
IDE:VS2019
C++
#include<stack>
#include<iostream>
using namespace std;
const int N = 100;
const int INF = 100000;
int p[N][N], d[N], path[N];
//分别存结点 距离 路径
void dijkstra(int bgn, int n) //bgn为出发节点,n表示图中节点总数
{
int i, j, min, min_num;
int mark[N] = { 0 };//标记为未确认
//更新初始距离
for (i = 1; i <= n; i++)
{
d[i] = p[bgn][i];
}
mark[bgn] = 1; d[bgn] = 0;
for (i = 1; i <n; i++)
{
min = INF;
//找到距离起点最近的点存在min_num,其距离存在min
for (j = 1; j <= n; j++)
{
if (!mark[j] && d[j] < min)
{
min = d[j];
min_num = j;
}
}
mark[min_num] = 1;//标记为已确认
//更新最短路径并记录最后一个中途结点
for (j = 1; j <=n; j++)
{
if (d[j] > min + p[min_num][j])
{
path[j] = min_num;//path[j]记录d[j]暂时最短路径的最后一个中途节点min_num,表明d[j]最后一段从节点min_num到节点j
d[j] = min + p[min_num][j];
}
}
}
}
void print(int bgn, int n) //bgn为出发节点,n表示图中节点总数
{
int i, j;
stack<int> q; //由于记录的中途节点是倒序的,所以使用栈(先进后出),获得正序
for (i = 2; i <=n; i++) //打印从出发节点到各节点的最短距离和经过的路径
{
j = i;
while (path[j] != -1) //如果j有中途节点
{
q.push(j); //将j压入堆
j = path[j]; //将j的前个中途节点赋给j
}
q.push(j);
cout << bgn << "=>" << i <<" length:"<< d[i]<<" path " << bgn;
while (!q.empty()) //先进后出,获得正序
{
cout << q.top();
//printf("%d ", q.top());//打印堆的头节点
q.pop(); //将堆的头节点弹出
}
printf("\n");
}
}
int main()
{
memset(path, -1, sizeof(path));//将path数组初始化为-1
int i, j, n = 6; //n为顶点个数,方便测试将数据写死
//任意两点间距离初始化为INF,自身为0
for (i = 1; i <= n; i++)
{
for (j = 1; j <=n; j++)
{
p[i][j] = (i == j ? 0 : INF);
}
}
//为方便测试将数据写死,下面注释内为如何输入数据
p[1][2] = 1; p[1][3] = 12; p[2][3] = 9; p[2][4] = 3; p[4][5] = 13; p[3][5] = 5; p[4][6] = 15; p[5][6] = 4;p[4][3]=4;//p[i][j]表示节点i到节点j的距离
/*
int vtx, side;//顶点总数 边总数
cin >>vtx>>side;
int vtx_1,vtx_2,dist;//点 距离
for(int i=0;i<side;i++){
cin>>vtx_1>>vtx_2>>dist;
p[vtx_1][vtx_2]=dist;
}
若输入数据请注意修改上面的顶点数
*/
dijkstra(1, n); //求从节点0出发到各节点的最短距离
print(1, n); //打印从节点0出发到各节点的最短距离和路径
return 0;
}
欢迎指正 畅所欲言
既来之,则赞之~
更多推荐
所有评论(0)