目录

  • 1. 应用场景-最短路径问题
  • 2. 迪杰斯特拉(Dijkstra)算法介绍
  • 3. 迪杰斯特拉(Dijkstra)算法过程
  • 4. 算法分析过程
  • 5. 代码实现

1. 应用场景-最短路径问题

  • 看一个应用场景和问题

  1. 胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从G点出发,需要分别把邮件分别送到 A, B, C , D, E, F 六个村庄
  2. 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里
  3. 问:如何计算出G村庄到其它各个村庄的最短距离?
  4. 如果从其它点出发到各个点的最短距离又是多少?

2. 迪杰斯特拉(Dijkstra)算法介绍

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

3. 迪杰斯特拉(Dijkstra)算法过程

  • 设置出发顶点为v,顶点集合V{v1,v2,vi…},v到V中各顶点的距离构成距离集合Dis,Dis{d1,d2,di…},Dis集合记录着v到图中各顶点的距离(到自身可以看作0,v到vi距离对应为di)
  1. 从Dis中选择值最小的di并移出Dis集合,同时移出V集合中对应的顶点vi,此时的v到vi即为最短路径
  2. 更新Dis集合,更新规则为:比较v到V集合中顶点的距离值,保留值较小的一个(同时也应该更新顶点的前驱节点为vi,表明是通过vi到达的)
  3. 重复执行两步骤,直到最短路径顶点为目标顶点即可结束

4. 算法分析过程

  • 先定义三个数组,分别是已访问节点、前驱节点、出发顶点到其他顶点的距离
//已访问顶点集合
class Visited_vertex{//记录各个顶点是否访问过  1表示访问过,0未访问,会动态更新public int[] already_arr; //每个下标对应的值为前一个顶点下标, 会动态更新public int[] pre_visited;//记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其它顶点的距离,会动态更新,求的最短距离就会存放到dispublic int[] dis;
}
  • 假设邻接矩阵如下,N(65535)表示不连通
  A B C D E F G
A{N,5,7,N,N,N,2};
B{5,N,N,9,N,N,3};
C{7,N,N,N,8,N,N};
D{N,9,N,N,N,4,N};
E{N,N,8,N,N,5,4};
F{N,N,N,4,5,N,6};
G{2,3,N,N,4,6,N};
  • 以G点为出发顶点,初始化后

  • 以G为出发顶点访问过一次后的情况

  • 经过G出发访问一轮后,继续选择并返回新的访问顶点, 比如访问G之后,就是以 A点作为新的访问顶点(注意不是出发顶点),遍历所有的顶点,即可得到

5. 代码实现

import java.util.Arrays;public class DijkstraAlgorithm {public static void main(String[] args) {char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};// 邻接矩阵int[][] matrix = new int[vertex.length][vertex.length];// 表示不可以连接final int N = 65535;matrix[0] = new int[]{N, 5, 7, N, N, N, 2};matrix[1] = new int[]{5, N, N, 9, N, N, 3};matrix[2] = new int[]{7, N, N, N, 8, N, N};matrix[3] = new int[]{N, 9, N, N, N, 4, N};matrix[4] = new int[]{N, N, 8, N, N, 5, 4};matrix[5] = new int[]{N, N, N, 4, 5, N, 6};matrix[6] = new int[]{2, 3, N, N, 4, 6, N};// 创建Graph对象Graph graph = new Graph(vertex, matrix);// 显示图graph.showGraph();// 以G作为出发顶点graph.dsj(6);graph.showDijkstra();}
}// 已访问顶点的集合
class VisitedVertex {// 记录各个顶点是否访问过 1表示访问过,0未访问过,会动态更新public int[] already_arr;// 每个下标对应的值为前一个顶点的下标,会动态更新public int[] pre_visited;// 记录出发顶点到其他所有顶点的距离,会动态更新public int[] dis;/*** 构造器** @param length 顶点个数* @param index  出发顶点的下标,比如G为顶点,下标就是6*/public VisitedVertex(int length, int index) {this.already_arr = new int[length];this.pre_visited = new int[length];this.dis = new int[length];// 初始化 dis 数组Arrays.fill(dis, 65535);// 设置出发顶点被访问过this.already_arr[index] = 1;// 设置出发顶点的访问距离为0this.dis[index] = 0;}// 判断index顶点是否被访问过public boolean in(int index) {return already_arr[index] == 1;}// 更新出发顶点到index顶点的距离public void updateDis(int index, int len) {dis[index] = len;}// 更新pre这个顶点的前驱顶点为index顶点public void updatePre(int pre, int index) {pre_visited[pre] = index;}// 返回出发顶点到index顶点的距离public int getDis(int index) {return dis[index];}// 继续选择并返回新的访问顶点,比如G访问后,就是A作为新的访问顶点(注意不是出发顶点)public int updateArr() {int min = 65535;int index = 0;for (int i = 0; i < already_arr.length; i++) {// 找出没有被访问过,且到出发顶点距离最短的点if (already_arr[i] == 0 && dis[i] < min) {min = dis[i];index = i;}}// 更新index顶点被访问过already_arr[index] = 1;return index;}// 显示最后的结果,将三个数组的情况输出public void show() {System.out.println("==========================");//输出already_arrfor (int i : already_arr) {System.out.print(i + " ");}System.out.println();//输出pre_visitedfor (int i : pre_visited) {System.out.print(i + " ");}System.out.println();//输出disfor (int i : dis) {System.out.print(i + " ");}System.out.println();char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int count = 0;for (int i : dis) {if (i != 65535) {System.out.print(vertex[count] + "(" + i + ") ");} else {System.out.println("N ");}count++;}System.out.println();}
}class Graph {// 顶点数组private char[] vertex;// 邻接矩阵private int[][] matrix;// 已访问的顶点的集合private VisitedVertex vv;public Graph(char[] vertex, int[][] matrix) {this.vertex = vertex;this.matrix = matrix;}// 显示图public void showGraph() {for (int[] link : matrix) {System.out.println(Arrays.toString(link));}}//显示结果public void showDijkstra() {vv.show();}// 更新index下标顶点到周围顶点的距离和周围顶点的前驱顶点private void update(int index) {int len = 0;// 遍历matrix[index]行int[] ints = matrix[index];for (int i = 0; i < ints.length; i++) {// len是出发顶点到index顶点的距离+从index顶点到i顶点的距离len = vv.getDis(index) + ints[i];// 如果i顶点没有被访问过,并且len小于出发顶点到i顶点的距离,就需要更新if (!vv.in(i) && len < vv.getDis(i)) {// 更新i顶点的前驱为index顶点vv.updatePre(i, index);// 更新出发顶点到i顶点的距离vv.updateDis(i, len);}}}/*** 算法实现** @param index 出发顶点对应的下标*/public void dsj(int index) {vv = new VisitedVertex(vertex.length, index);// 更新index顶点到周围顶点的距离和前驱顶点update(index);for (int i = 0; i < vertex.length; i++) {// 选择并返回新的访问点index = vv.updateArr();// 更新index顶点到周围顶点的距离和前驱顶点update(index);}}}

算法7:迪杰斯特拉算法相关推荐

  1. 0096 克鲁斯卡尔算法,迪杰斯特拉算法

    /*  * 克鲁斯卡尔算法  * 1.用来求加权连通图的最小生成树的算法  * 2.思想:按照权值从小到大的顺序,选择n-1条边,并保证这n-1条边不构成回路  * 3.先构造一个只含n个顶点的森林, ...

  2. 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】

    图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...

  3. 数据结构第十二天——普利姆算法和迪杰斯特拉算法

    普利姆(Prim)算法求最小生成树,也就是在包含 n个顶点的连通图中,找出只有(n-1)条边包含所有 n个顶点的连通子图,也就是所谓的极小连通子图 最小生成树:给定一个带权的无向连通图,如何选取一棵生 ...

  4. 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)

    最小生成树 什么是最小生成树 是一棵树 - 无回路 - |V|个顶点一定有|V|-1条边 是生成树 - 包含全部顶点 - |V|-1条边全在图里 贪心算法 什么是"贪":每一步都要 ...

  5. java迪杰斯特拉算法_迪杰斯特拉算法完整代码(Java)

    package com.rao.graph; import java.util.*; /** * @author Srao * @className Dijkstra * @date 2019/12/ ...

  6. 【数据结构与算法】迪杰斯特拉算法的介绍和最短路径问题程序实现

    目录 1. 迪杰斯特拉算法的介绍 2. 迪杰斯特拉算法的原理 3. 最短路径问题介绍 1. 迪杰斯特拉算法的介绍 迪杰斯特拉(Dijkstra)算法是典型求两点之间最短路径算法.它的主要特点是以起始点 ...

  7. 计算机网络课程实验4——编程实现路由算法(迪杰斯特拉算法)

    实验目的: 运用各种编程语言实现基于 Dijkstra 算法的路由软件. 实验意义: 通过本实验,使学生能够对路由原理和路由算法有进一步的理解和掌握. 实验步骤: 1, 选择合适的编程语言编程实现基于 ...

  8. 最短路径的两种算法(迪杰斯特拉算法和弗洛伊德算法)

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

  9. 算法系列——迪杰斯特拉算法(Dijkstra)

    本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节.我在努力! 本篇文章编程语言为Python,供参考. 迪杰斯特拉算法(Dijkstra) 典型最短路径算法 ...

  10. 最短路径算法之迪杰斯特拉算法(Dijkstra)和佛洛依德算法(Floyd)

    今天学习了这两种算法,都是用来求最小路径的算法,但是迪杰斯特拉算法只能从某个特定点到所有点的最短路径,而佛洛依德算法可以查出任意点到任意点的最小路径. 迪杰斯特拉: package dijkstra; ...

最新文章

  1. 云计算DHT分布式存储
  2. *2 echo、printf、mkdir命令的应用
  3. Android游戏的心跳效果
  4. NLP算法工程师对NLP的一些看法
  5. iframe父子级页面传值支持跨域访问javascript
  6. 马斯克:如果我不担任CEO 特斯拉就会完蛋
  7. C/C++教程 第十二章 —— MFC的基本使用
  8. BeanUtils笔记
  9. uniapp vite 路由跳转、登录模块封装(非无感登录)
  10. matlab 图像傅里叶逆变换,用MATLAB实现图像的傅里叶变换.ppt
  11. 多家高校网站被挂马 用户应小心QQ盗号木马
  12. 对话旷视CEO印奇:一文看尽他创业九年的思考
  13. Multisim3.8应用实例
  14. 牛客网C语言编程初学者入门训练135题
  15. TimesTen 应用层数据库缓存学习:12. 管理缓存环境
  16. html卡片式ui,十分钟认识UI设计中卡片式设计技法
  17. 【Book 133】Illuminate-Harness the Positive Power of negative Thinking
  18. mysql表分段删除_SQL删除数据(分段实现大量数据的删除操作)
  19. Android 环境的安装
  20. 超级玛丽/超级马里奥

热门文章

  1. Lumiprobe蛋白质定量丨QuDye 蛋白定量试剂盒
  2. 电子计算机的字母是什么意思,电脑硬件的型号中的数字和字母都代表什么意思...
  3. xcode中添加新字体【ttf】
  4. 如何应对用智行火车票购买机票后的高额退改手续费???
  5. php复姓怎么排序,这些高大上的复姓,你喜欢哪个?
  6. 无刷直流电机、永磁同步电机与开关磁阻电机
  7. 关于使用WinDebug查看线程死锁问题
  8. rails中arity的使用
  9. 化工单元操作复习题(含答案)
  10. 你知道GPU对Ansys Fluent仿真有多重要吗?