1 Dijkstra算法

1.1 算法基本信息

  • 解决问题/提出背景

    • 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径)
  • 算法思想

    • 贪心算法

      • 按路径长度递增的次序,依次产生最短路径的算法
    • 【适用范围】Dijkstra算法仅适用于【权重为正】的图模型中
  • 时间复杂度

    • O(n^3)
  • 补充说明

    • 亦可应用于【多源最短路径】(推荐:Floyd算法(动态规划,O(n^3)))

      • Dijkstra 时间复杂度:O(n^3)

1.2 算法描述

  • 1.2.1 求解过程(具体思路)
  • 1.2.2 示例

1.2 编程复现

  • 1> 定义图模型(邻接矩阵表示法)的【基本存储结构体】
# define MaxInt 32767 // 表示极大值 即 ∞ (无穷大)
# define MVNum 100 // 最大顶点数 typedef int VertexType; // 假设顶点的数据类型为整型 typedef int ArcType; // 假设Vi与Vj之边的权值类型为整型 typedef struct {
VertexType vexs[MVNum]; // 顶点表 (存储顶点信息)
ArcType arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum,arcnum; // 图的当前顶点数与边数
}AMGraph; // Adjacent Matrix Graph 邻接矩阵图
  • 2> 定义 Dijkstra 算法的【辅助数据结构体】
bool S[MVNum]; // S[i] 记录从源点V0到终点Vi是否已被确定为最短路径长度  【划分确定与未确定: 跟贪心算法的适用范围(不可取消性)有直接联系】
// true:表已确定;false:表尚未确定
ArcType D[MVNum]; // D[i] 记录从源点V0到终点Vi的【当前】最短路径【长度】
int Path[MVNum]; // Path[i] 记录从源点V0到终点Vi的【当前】最短路径上【Vi的[直接前驱]的顶点序号】
  • 3> 初始化(邻接矩阵)带权有向图的图模型
void InitAMGraph(AMGraph &G){
cout<<"Please Input Vertexs Number:";
cin>>G.vexnum;
cout<<"\nPlease Directed Edges Number:";
cin>>G.arcnum; for(int i=0;i<MVNum;i++){
for(int j=0;j<MVNum;j++){
if(i!=j){ // 【易错】 初始化<Vi, Vj>时: <Vi,Vj> 路径长度无穷大 (i!=j)
G.arcs[i][j] = MaxInt;
} else { // 【易错】 初始化<Vi, Vj>时: <Vi,Vi>【自回环】路径长度为0 (i==i)
G.arcs[i][j] = 0;
}
}
}
for(int i=0;i<G.vexnum;i++){
G.vexs[i] = i;
}
cout<<"\nPlease Input All Directed Edges and their Weight now:";
cout<<"\nDirected Edges(i,j,weight): "<<endl;
int i,j;
int weight;
for(int k=0;k<G.arcnum;k++){
// cout<<"("<<(k+1)<<") ";
cin>>i;cin>>j;cin>>weight;
G.arcs[i][j] = weight;
}
cout<<endl;
}
  • 4> Dijkstra算法:求解单源最短路径
void ShortestPath_Dijkstra(AMGraph G, int V0){
//step1 n个顶点依次初始化
int n =G.vexnum;
for(int v=0;v<n;v++){
S[v] = false;
D[v] = G.arcs[V0][v];
if(D[v]<MaxInt){
Path[v] = V0;
} else {
Path[v] = -1;
}
}
//step2 将源点V0划入已确定集合S中
S[V0] = true;
D[V0] = 0; // 源点V0到源点V0的最短路径长度必然为0
//step3 贪心算法策略:
// 3.1 循环遍历所有结点:
// 3.2 先确定当前最短路径的终点v;
// 3.3 然后,将v划入已确定集合S中;
// 3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径
int v;
int min;
D[G.vexnum] = MaxInt;
for(int i=1;i<n;i++){//3.1循环遍历所有结点 (即 求从源点V0到图中每一顶点(共计n-1个顶点)的最短路径)
//3.2 确定当前最短路径的终点v;
min = MaxInt;
for(int w=0;w<n;w++){
if(S[w]==false && D[w]<min){//比本轮循环中,已知的最短路径还短 【易错/易漏】 S[w]==false : 必须满足当前结点 Vw 属于尚未确定的结点
v = w;
min = D[w];
}
}
//3.3 然后,将v划入已确定集合S中;
S[v] = true;
//3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径
for(int w=0;w<n;w++){
//↓更新Vw结点的最短路径长度为 D[v] + G.arcs[v][w]
//cout<<"S["<<w<<"]:"<<S[w]<<"D["<<v<<"]"<<D[v]<<"G.arcs["<<v<<"]["<<w<<"]"<<"D["<<w<<"]"<<D[w]<<endl;
if(S[w]==false && (D[v] + G.arcs[v][w] < D[w])){//【易错/易漏】 S[w]==false : 必须满足当前结点 Vw 属于尚未确定的结点
D[w] = D[v] + G.arcs[v][w];
Path[w] = v; // 更新 结点Vw的前驱为 v
}
}
v = G.vexnum;
}
}
  • 5> 输出结果 D[i]、Path[j]
void OutputD(AMGraph G, int V0){
cout<<"Shortest Distance Weight of the Pair of Directed Vertices("<<V0<<", j):"<<endl;
for(int j=0;j<G.vexnum;j++){
cout<<D[j]<<"\t";
}
cout<<endl;
} void OutputPath(AMGraph G,int V0){
cout<<"Shortest Distance Path("<<V0<<",j) of the Pair of Directed Vertices:"<<endl;
for(int j=0;j<G.vexnum;j++){
cout<<Path[j]<<"\t";
}
cout<<endl;
}
  • 6> 执行:Main函数
int main(){
int V0; //源点V0的下标
AMGraph G;
InitAMGraph(G); cout<<"Please Input the Index of Source Node 'V0':";
cin>>V0;
ShortestPath_Dijkstra(G, V0);
OutputD(G, V0);
OutputPath(G, V0);
return 0;
}
  • 7> Test: Output of Main
Please Input Vertexs Number:6

Please Directed Edges Number:8

Please Input All Directed Edges and their Weight now:
Directed Edges(i,j,weight):
1 2 5
0 2 10
3 5 10
4 3 20
0 4 30
2 3 50
4 5 60
0 5 100 Please Input the Index of Source Node 'V0':0 Shortest Distance Weight of the Pair of Directed Vertices(0, j):
0 32767 10 50 30 60 Shortest Distance Path(0,j) of the Pair of Directed Vertices:
0 -1 0 4 0 3

2 参考文献

  • 《数据结构(C语言版/ 严蔚敏 李冬梅 吴伟民 编)》

[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)的更多相关文章

  1. 图->最短路径->单源最短路径(迪杰斯特拉算法Dijkstra)

    文字描述 引言:如下图一个交通系统,从A城到B城,有些旅客可能关心途中中转次数最少的路线,有些旅客更关心的是节省交通费用,而对于司机,里程和速度则是更感兴趣的信息.上面这些问题,都可以转化为求图中,两 ...

  2. 单源最短路径-迪杰斯特拉算法(Dijkstra's algorithm)

    Dijkstra's algorithm 迪杰斯特拉算法是目前已知的解决单源最短路径问题的最快算法. 单源(single source)最短路径,就是从一个源点出发,考察它到任意顶点所经过的边的权重之 ...

  3. 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析

    什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...

  4. 最短路径-迪杰斯特拉(dijkstra)算法及优化详解

    简介: dijkstra算法解决图论中源点到任意一点的最短路径. 算法思想: 算法特点: dijkstra算法解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树.该算法常用于路由算 ...

  5. 最短路径 - 迪杰斯特拉(Dijkstra)算法

    对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...

  6. JS实现最短路径之迪杰斯特拉(Dijkstra)算法

    最短路径: 对于网图来说,最短路径是指两个顶点之间经过的边上权值和最少的路径,我们称第一个顶点是源点,最后一个顶点是终点 迪杰斯特拉 ( Dijkstra) 算法是并不是一下子就求出 了 Vo 到V8 ...

  7. 最短路径算法-迪杰斯特拉(Dijkstra)算法在c#中的实现和生产应用

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止 贪心算法(Greedy ...

  8. 迪杰斯特拉Dijkstra算法介绍

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  9. [从今天开始修炼数据结构]图的最短路径 —— 迪杰斯特拉算法和弗洛伊德算法的详解与Java实现

    在网图和非网图中,最短路径的含义不同.非网图中边上没有权值,所谓的最短路径,其实就是两顶点之间经过的边数最少的路径:而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,我们称路径上第 ...

  10. 数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++

    数据结构图之三(最短路径--迪杰斯特拉算法)   [1]最短路径 最短路径?别乱想哈,其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两 ...

随机推荐

  1. python3 pyinstaller

    一.安装python.pywin32.pyinstaller库 二.官网:https://pyinstaller.readthedocs.io/en/v3.3.1/usage.html#general ...

  2. Mysql读写分离 及高可用高性能负载均衡实现

    什么是读写分离,说白了就是mysql服务器读的操作和写的操作是分开的,当然这个需要两台服务器,master负责写,slave负责读,当然我们可以使用多个slave,这样我们也实现了简单意义上的高可用和 ...

  3. Java 基础 - 泛型类/泛型方法/类型通配符'?' 的用法及栗子

    笔记: /**1.定义一个PairTest泛型类, 测试泛型 类 Pair的用法 * class Pair<T>{ * private T first; * private T secon ...

  4. virtualBox+centOS的一些报错

    step1: 安装系统后进入命令行模式 安装virtualBox:https://www.virtualbox.org/wiki/Downloads 下载centOS7镜像:https://www.c ...

  5. laravel本地开发环境的安装及配置 - Windows:安装 Laravel Homestead 虚拟机

    一.安装 VirtualBox-5.2.22-126460-Win.exe 和 vagrant_2.2.2_x86_64.msi(可视化安装包安装); 安装在D盘 二.导入 Homestead Vag ...

  6. 第92题:反转链表II

    一. 问题描述 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NUL ...

  7. 基本数据类型-MySQL

    整型: TINYINT 最小 1个字节 -128~127 0~255 SMALLINT 较小 2个字节 -32768~32767 0~65535 MEDIUMINT 中等大小 3个字节 略   INT ...

  8. E:only-child

    E:only-child 语法: E:only-child { sRules } 说明: 匹配父元素仅有的一个子元素E.大理石机械构件维修 要使该属性生效,E元素必须是某个元素的子元素,E的父元素最高 ...

  9. MongoDB 运维实总结

    一.MongoDB 集群简介 MongoDB是一个基于分布式文件存储的数据库,其目的在于为WEB应用提供可扩展的高性能数据存储解决方案.下面将以3台机器介绍最常见的集群方案.具体介绍,可以查看官网 h ...

  10. python基础-垃圾回收机制

    垃圾回收 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 引用计数 原理:当一个对象的引用被创建或者复制时,对象的引用计数加1:当一个对象的引用被销毁时,对象 ...