Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

迪杰斯特拉算法采用的是贪心算法,对于最短路径来说,就是求出发点到终点过程中的每一步的最优解。本次就以最短路径为例,假设要求0到5的最短路径,图示如下:

思路:将起点作为第一个标记点,其余点均为未标记点。以最初标记点为对象,遍历未标记点,寻找距离最初标记点最近的未标记点并将这个未标记点变为标记点,且两点之间的路径为最优解(注:最后求出的是起点到所有点的最短路径)。

分析:如图,0为标记点,其余点均为未标记点,其中未标记点1离0最近,将1纳入标记点。并可知1的父节点为0。

以0,1为连接点,从未标记继续寻找下一个到起点0最近的未标记点2(此处如有疑惑,先继续看),将2纳入标记点。并可知2的父节点为1。

继续以0,1,2为连接点,寻找离0最近的未标记点3,将3纳入标记点,并可知3的父节点为1。

继续以0,1,2,3为连接点,寻找离0最近的未标记点5,将5纳入标记点。并可知5的父节点为3.

继续以0,1,2,3,5为连接点,寻找离0最近的未标记点4,将4纳入标记点。并可知4的父节点为1。

此时所有结点都转化为了标记点,到此我们已经找到了起点0到各个点的最短路径。根据上述的父子关系则可逆推出最短路径。以0到5为例:5的父亲为3,可推5->3。3的父亲为1,可推出5->3->1。又1的父亲为0,即5->3->1->0。将其逆序,则可得出最短路径0->1->3->5。

代码实现(C语言):

//Dijsktra算法
//最短路径
#include<stdio.h>
#include<stdlib.h>
#define N 100typedef int ElementType;typedef struct Ver {struct Ver *father;char ch;int id;int minLength;int flag;//表示给结点是否被标记,0表示未被标记,1 标记
} Ver,*Vertex;//初始化城市结点,并接收城市个数
int InitialCitys(Vertex vertex[]) {int m,i=0;//'m'城市数量printf("请输入城市数量:");scanf("%d",&m);//初始化vertex,给vertex分配空间for(i=0; i<m; i++) {vertex[i]=(Vertex)malloc(sizeof(Ver));vertex[i]->minLength=99999;//假设99999为无穷大vertex[i]->flag=0;}printf("\n请输入城市名称:");i=0;while(i<m) {char c;//消除空格和回车while((c=getchar())==' '||c=='\n');vertex[i]->ch=c;vertex[i]->id=i;i++;}return m;
}//根据城市名称获取对应下标
int getCityIndex(Vertex vertex[],char ch,int m) {for(int i=0; i<m; i++) {if(vertex[i]->ch==ch) return vertex[i]->id;}
}//初始化路径,并接收路径个数
void InitialPath(ElementType path[][N],Vertex vertex[],int m) {int n,i,j;//初始化pathfor(int i=0; i<m; i++) {for(int j=0; j<m; j++)path[i][j]=99999;}printf("请输入路径数量:");scanf("%d",&n);i=0;while(i<n) {printf("\n请输入路径:");char c;int p,q;//消除空格和回车while((c=getchar())==' '||c=='\n');p=getCityIndex(vertex,c,m);while((c=getchar())==' '||c=='\n');q=getCityIndex(vertex,c,m);scanf("%d",&path[p][q]);path[q][p]=path[p][q];i++;}return;
}//输入起点和终点,并将每个城市初始结点至为start
void InputStartAndEnd(char *start,char *end,Vertex vertex[],int m) {printf("\n请输入起点和终点(A->B):");char c;//消除空格和回车while((c=getchar())==' '||c=='\n');*start=c;while((c=getchar())==' '||c=='\n');*end=c;//将起点标记int t=getCityIndex(vertex,start[0],m);vertex[t]->flag=1;vertex[t]->minLength=0;vertex[t]->father=NULL;return;
}//建立最短路径
void BuildShortPath(Vertex vertex[],ElementType path[][N],char start,char end,int m) {//遍历每个结点共需要循环m-1次//每次遍历将未标记点转化为标记点for(int i=1; i<m; i++) {int minLength=99999;int t;//遍历未标记for(int j=0; j<m; j++) {if(vertex[j]->flag==0) {//遍历已标记for(int k=0; k<m; k++) {if(vertex[k]->flag!=0) {//求出该未标记点到标记点的最短距离//如果两城市之间距离小于最小距离,则更新最短距离int all_p=path[k][j]+vertex[k]->minLength;if(all_p<vertex[j]->minLength) {vertex[j]->minLength=all_p;vertex[j]->father=vertex[k];}}}//判断该未标记点是否是所有未标记点到标记点的最短距离if(vertex[j]->minLength<minLength) {minLength=vertex[j]->minLength;t=j;}}}vertex[t]->flag=1;
//      printf("第%d次标点为%c,父亲为:%c,路径长度为%d\n",i,vertex[t]->ch,vertex[t]->father->ch,vertex[t]->minLength);}
}//输出单个或全部最短路径
void PrintAllPath(Vertex vertex[],char start,int m,int front,int tail) {if(tail-front==1) printf("%c到%c最短路径为:",start,vertex[front]->ch);elseprintf("\n\n*以下是%c到 各个点的最短路径*:\n",start);//指定输出最短路径的范围for(int i=front; i<tail; i++) {char end=vertex[i]->ch;//如果起点和终点相同,则退出if(end==start) continue;printf("%c到%c最短路径为:",start,end);int j=getCityIndex(vertex,end,m);Vertex p=vertex[j];int minLength=p->minLength;int n=0;char ch[N];//因为结果是逆序的,所以要颠倒一下while(p!=NULL) {ch[n++]=p->ch;p=p->father;}printf("%c",ch[n-1]);for(int i=n-2; i>=0; i--) {printf("->%c",ch[i]);}printf("\n最短路径长度为:%d\n",minLength);}
}int main() {//定义vertex指针型结构体数组,并分配空间Vertex vertex[N];//初始化城市结点,并接收城市个数int m=InitialCitys(vertex);//用处存储两个数之间的距离ElementType path[N][N];//初始化路径,并接收路径个数InitialPath(path,vertex,m);//输入起点和终点,并将每个城市初始结点至为startchar start,end;InputStartAndEnd(&start,&end,vertex,m);//建立最短路径BuildShortPath(vertex,path,start,end,m);//获取end的下标int tail=getCityIndex(vertex,end,m);//输出最短路径PrintAllPath(vertex,start,m,tail,tail+1);//输出全部最短路径PrintAllPath(vertex,start,m,0,m);
}

C语言测试数据:

6
012345
8
012
026
123
134
147
245
351
453
05

代码实现(Java):

import java.util.ArrayList;
import java.util.List;public class Dijkstra {static int[][] matrix = new int[6][6];final static int N = 10000;public static void main(String[] args) {//邻接矩阵matrix[0] = new int[]{N, 2, 6, N, N, N};/*0*/matrix[1] = new int[]{2, N, 3, 4, 7, N};/*1*/matrix[2] = new int[]{6, 3, N, N, 5, N};/*2*/matrix[3] = new int[]{N, 4, N, N, N, 1};/*3*/matrix[4] = new int[]{N, 7, 5, N, N, 3};/*4*/matrix[5] = new int[]{N, N, N, 1, 3, N};/*5*///已标记点集合List<Vertex> Marked = new ArrayList<>();Vertex vt0 = new Vertex();vt0.id = 0;vt0.minLenth = 0;Marked.add(vt0);//未标记点集合List<Vertex> UnMarked = new ArrayList<>();for (int i = 0; i < 5; i++) {Vertex vtx = new Vertex();vtx.id = i+1;UnMarked.add(vtx);}//将未标记点集合中的点转移到已标记点集合int order = 1;while(!UnMarked.isEmpty()){Vertex vtx = FindVer(Marked, UnMarked);UnMarked.remove(vtx);Marked.add(vtx);System.out.println("第"+order+"次标号,顶点"+vtx.id+"的标号为:(" + vtx.father.id + "," +vtx.minLenth + ")");order++;}//输出路径for(Vertex v :Marked){if(v.id == 5){System.out.println("0-5的最短路径长度为:" + v.minLenth);System.out.print("逆推得最优路径为:" + "5");while(v.id != 0){v = v.father;System.out.print( " -> " + v.id);}}} }static Vertex FindVer(List<Vertex> Marked, List<Vertex> UnMarked){int M = 10000;Vertex v = null;for (Vertex ve : UnMarked) {for (Vertex vr : Marked) {int all_p = vr.minLenth + matrix[vr.id][ve.id];if (all_p <= ve.minLenth) {ve.minLenth = all_p;ve.father = vr;}}if (ve.minLenth < M) {M = ve.minLenth;v = ve;}}return v;}}
class Vertex {public int id;public Vertex father;public int minLenth = 10000;
}

一言:

邂逅的频繁,谁知那并非偶然。

最短路径(Dijkstra算法)相关推荐

  1. 最短路径-Dijkstra算法与Floyd算法

    最短路径-Dijkstra算法与Floyd算法 原文:https://www.cnblogs.com/smile233/p/8303673.html 一.最短路径 ①在非网图中,最短路径是指两顶点之间 ...

  2. 分支限界法:单源最短路径--dijkstra算法

    单源最短路径–dijkstra算法 前面已经多次介绍过dijkstra算法是贪心算法,是动态规划,实际上可以从分支限界的角度来理解: 分支限界法 分支限界法,实际上就是回溯法,一般意义的回溯法是基于深 ...

  3. 最短路径——Dijkstra算法以及二叉堆优化(含证明)

    一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...

  4. python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  5. 使用邻接矩阵实现有向图最短路径Dijkstra算法

    题目描述: 用邻接矩阵存储有向图,实现最短路径Dijkstra算法,图中边的权值为整型,顶点个数少于10个. 输入描述 首先输入图中顶点个数和边的条数: 再输入顶点的信息(字符型): 再输入各边及其权 ...

  6. 最短路径——Dijkstra算法与Floyd算法

    最短路径 Dijkstra算法 C语言代码实现 代码解析 Floyd算法 算法解析 C语言代码实现 最短路径问题 最短路径问题是我们经常会面临的一种决策问题.在图论中,非网图(边没有权值)的最短路径就 ...

  7. 最短路径(Dijkstra算法)(c/c++)

    Dijkstra是一种求单源点最短路径的算法,即求某一个顶点到其余各顶点之间的最短路径,下面采用邻接矩阵来存储图中信息 算法思路为: 1,假设v0是源点,s是已求得最短路径的终点集合,用D[i]来保存 ...

  8. 数据结构与算法—单源最短路径dijkstra算法

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  9. C++ 实现带权有向图的单源点最短路径Dijkstra算法(完整代码)

    首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v0到每个终点vi的最短路径的长度. 它的初态为:若从v0到vi有弧,则D[i]为弧上的权值:否则,置D[i]为∞. 显然,长度为 ...

  10. 最短路径——Dijkstra算法HDU Today(hdu2112)

    关于本题的floyd解法:http://blog.csdn.net/sm9sun/article/details/53282826 上篇博文介绍了floyd解决最短路径的方法,然而由于floyd极大的 ...

最新文章

  1. Python3.8.5最新版安装教程(含老版本卸载教程)
  2. 浅谈python语言_浅谈Python语言基础知识点!
  3. gitignore 文件生效办法
  4. nstruts2.0发布前奏---浅谈struts和依赖注入在项目中的应用
  5. 使用Oracle验证外部数据
  6. UltraEdit如何自动换行
  7. 基于BFS+DFS+CoordinateDescent的motion planning设计思路
  8. NASA好奇号发来战报,32368张火星路况实拍数据集上线 | 资源
  9. 这个机器人花盆,给你的植物长了脚脚
  10. 8086的内中断典型如int 21h的分析
  11. 分解原理_原理篇 | 推荐系统之矩阵分解模型
  12. 扇贝有道180915每日一句
  13. SAR空间自回归模型
  14. 一次完整的 RPC 流程
  15. 部署在服务器上的行驶证识别api接口
  16. macOS Monterey 12.6.2 (21G320) 正式版 ISO、IPSW、PKG 下载
  17. Steam游戏服务器配置选择 IP
  18. [重装系统系列]fcitx 小企鹅输入法 安装 in ubuntu 15.04
  19. 继明哥的否定之后,java泰又出新作!明哥接码!
  20. Android笔记系列--获取手机号码

热门文章

  1. 智能养殖系统解决方案
  2. Marklogic学习 —— XQuery语法之排序
  3. win10 nginx 开机自启(亲测有效)
  4. 手机纳米镀膜技术教程_纳米技术将在医疗保健的未来中发挥巨大作用
  5. oracle 强制建视图,11.2.6 强制创建视图
  6. Openjudge:字符串的最大跨距
  7. 霍洛维茨极品创业鸡汤 让创业者走出绝望
  8. python数据分析 知乎_Python数据分析揭秘知乎大V的小秘密
  9. 微信小程序全方位解析
  10. 爱丽丝性能服务器,《爱丽丝:疯狂回归》 修改AliceCompat.ini完全发挥CPU性能