Dijkstra算法——邻接矩阵实现+路径记录

本文是在下面这篇文章的基础上做了一些补充,增加了路径记录的功能。具体Dijkstra的实现过程可以参考下面的这篇文章。

jarvan:Dijkstra算法详解 通俗易懂\](Dijkstra算法详解 通俗易懂 - jarvan的文章 - 知乎 https://zhuanlan.zhihu.com/p/338414118) 创建 GraphAdjMat 类 GraphAdjMat 类用来实现图的邻接矩阵,方便后续的测试,具体代码如下: ```java package algorithm.graph; import java.util.ArrayList; import java.util.List; public class GraphAdjMat { private List vertices; private List> adjMat; /** * 构造函数 * @param vertices 顶点列表 * @param edges 边 */ public GraphAdjMat(int[]vertices, int[][]edges) { this.vertices = new ArrayList<>(); this.adjMat = new ArrayList<>(); for(int v : vertices) { addVertex(v); } for(int[]e : edges) { addEdge(e[0],e[1],e[2]); } //设置顶点自己到自己的权重为0 for(int i=0; i> getAdjMat() { return this.adjMat; } /** * 添加顶点 */ public void addVertex(int val) { int n = vertices.size(); vertices.add(val); List newRow = new ArrayList<>(); for(int i=0; i row : adjMat) { row.add(-1); } } /** * 移除顶点 */ public void removeVertex(int index) { if(index < 0 || index >= vertices.size()) { throw new IndexOutOfBoundsException(); } vertices.remove(index); adjMat.remove(index); for(List row : adjMat) { row.remove(index); } } /** * 添加边 * @param i 顶点1 * @param j 顶点2 * @param weight 边权重 */ public void addEdge(int i, int j, int weight) { if(i<0||j<0||i>=vertices.size()||j>=vertices.size()||i==j) { throw new IndexOutOfBoundsException(); } adjMat.get(i).set(j, weight); adjMat.get(j).set(i, weight); } /** * 移除边 */ public void removeEdge(int i, int j) { if(i<0||j<0||i>=vertices.size()||j>=vertices.size()||i==j) { throw new IndexOutOfBoundsException(); } adjMat.get(i).set(j, -1); adjMat.get(j).set(i, -1); } public void print() { System.out.println("adj mat:"); for(List row : adjMat) { for(int v : row) { System.out.printf("%3d", v); } System.out.println(); } } } ``` GraphAdjMat 类中提供了增加顶点、移除顶点、增加边和移除边的操作。 创建 DijkstraAlg 类 该类用于实现 Dijkstra 算法,并打印指定点到所有点的最短距离和路径信息 ```java package algorithm.graph; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Dijkstra 算法 */ public class DijkstraAlg { public static void main(String[]args) { char[]vertexNames = {'A','B','C','D'}; int[]vertices = {1,2,3,4}; int[][]edges = {{0,1,1},{0,3,6},{1,2,4},{1,3,1},{2,3,1}}; //构建邻接矩阵 GraphAdjMat adjMat = new GraphAdjMat(vertices, edges); adjMat.print(); int startVertex = 0; List result = dijkstra(adjMat.getAdjMat(),startVertex); System.out.println("dijkstra result: "); for(int i=0; i %s distence : %d ; ",vertexNames[startVertex], vertexNames[i], result.get(i).distence); List path = result.get(i).path; System.out.print("A -> "); for(int j=0; j ",vertexNames[path.get(j)]); }else { System.out.printf("%s\n", vertexNames[path.get(j)]); } } } } public static List dijkstra(List> graph, int startVertex) { int len = graph.size(); List result = new ArrayList<>(len); int[]notFound = new int[len]; //初始化 result for(int i=0; i(); result.add(i, shortestPath); } ShortestPath startVertexPath = new ShortestPath(); startVertexPath.distence = 0; startVertexPath.path = new ArrayList<>(0); result.set(startVertex,startVertexPath); //初始化 notFound for(int i=0; i> recordPathMap = new HashMap<>(); for(int i=1; i 0 && notFound[j] < min) { min = notFound[j]; minIndex = j; } } result.get(minIndex).distence = min; notFound[minIndex] = -1; //刷新 notFound for(int j=0; j 0 用来确保 minIndex 顶点有边,result[j] == -1 用来确保 j 点没有在结果集中 if(graph.get(minIndex).get(j) > 0 && result.get(j).distence == -1) { int newDistence = result.get(minIndex).distence + graph.get(minIndex).get(j); //计算合并距离如果小于直接到j点的距离,或者无法到达j点事将新距离刷新到notFound中 if(newDistence < notFound[j] || notFound[j] == -1) { notFound[j] = newDistence; if(!recordPathMap.containsKey(j)) { List tempList = new ArrayList<>(1); tempList.add(minIndex); recordPathMap.put(j, tempList); }else { recordPathMap.get(j).add(minIndex); } } } } } System.out.println(recordPathMap); //推到路径 for(int i=0; i())); result.get(i).path.add(i); } return result; } public static void printArr(int[]arr, String arrName) { System.out.print(arrName); for(int i : arr) { System.out.printf("%3d", i); } System.out.println(); } static class ShortestPath { public int distence; public List path; } } ``` 代码在原文代码的基础上通过增加 recordPathMap 来记录最短路径,最终打印最短路径距离和对应路劲信息。 ![在这里插入图片描述](https://file.jishuzhan.net/article/1744597918314139649/6741885e57b92bb8dcb541ae619d9f10.webp)

相关推荐
再__努力1点7 分钟前
【76】Haar特征的Adaboost级联人脸检测全解析及python实现
开发语言·图像处理·人工智能·python·算法·计算机视觉·人脸检测
溟洵7 分钟前
【算法C++】链表(题目列表:两数相加、两两交换链表中的节点、重排链表、合并 K 个升序链表、K 个一组翻转链表7)
数据结构·c++·算法·链表
_OP_CHEN8 分钟前
【C++数据结构进阶】玩转并查集:从原理到实战,C++ 实现与高频面试题全解析
数据结构·c++·算法
gugugu.8 分钟前
算法:hot100---128. 最长连续序列
算法
天呐草莓14 分钟前
支持向量机(SVM)
人工智能·python·算法·机器学习·支持向量机·数据挖掘·数据分析
zore_c26 分钟前
【数据结构】队列——超详解!!!(包含队列的实现)
c语言·网络·数据结构·c++·笔记·算法·链表
小杰帅气27 分钟前
智能指针喵喵喵
开发语言·c++·算法
智驱力人工智能37 分钟前
守护生命的水上之眼 无人机人员落水检测系统的技术攻坚与应用实践 无人机溺水识别 山区水库无人机落水检测系统 水域安全无人机部署指南
大数据·人工智能·算法·安全·无人机·边缘计算
hweiyu0038 分钟前
排序算法选型决策树
算法·排序算法
蓝色汪洋3 小时前
xtu oj矩阵
算法