java实现Dijkstra算法

本文介绍了Dijkstra算法,用于找到加权连通图中起点到所有其他顶点的最短路径。通过贪心法思想,进行多次查找,每次选择未遍历顶点中离起点最近的一个。文章提供了一个具体的编码示例,讨论了算法的时间复杂度,并提醒读者注意Dijkstra算法不适用于含有负权值的图,以及与Prim算法的区别。
摘要由CSDN通过智能技术生成

1 问题描述
何为Dijkstra算法?

Dijkstra算法功能:给出加权连通图中一个顶点,称之为起点,找出起点到其它所有顶点之间的最短距离。

Dijkstra算法思想:采用贪心法思想,进行n-1次查找(PS:n为加权连通图的顶点总个数,除去起点,则剩下n-1个顶点),第一次进行查找,找出距离起点最近的一个顶点,标记为已遍历;下一次进行查找时,从未被遍历中的顶点寻找距离起点最近的一个顶点, 标记为已遍历;直到n-1次查找完毕,结束查找,返回最终结果。

2 解决方案
2.1 使用Dijkstra算法得到最短距离示例

此处借用文末参考资料1博客中一个插图(PS:个人感觉此图描述简单易懂):

在这里插入图片描述

在这里插入图片描述

2.2 具体编码
Dijkstra复杂度是O(N^2),如果用binary heap优化可以达到O((E+N)logN),用fibonacci heap可以优化到O(NlogN+E) 。

注意,Dijkstra算法只能应用于不含负权值的图。因为在大多数应用中这个条件都满足,所以这种局限性并没有影响Dijkstra算法

Dijkstra算法是用于解决单源最短路径问题的一种高效算法,特别是在有向无环图(DAG)或带权重的边的图中。在Java实现Dijkstra算法,你可以使用优先队列(通常使用`java.util.PriorityQueue`)来存储尚未确定最短路径的节点,以及一个哈希映射或邻接表来存储图的结构。 以下是Java实现Dijkstra算法的一个基本步骤: 1. 初始化:创建一个HashMap或类似的数据结构,将起点的距离设为0,其他所有节点的距离设为无穷大,同时标记为未访问。 2. 创建优先队列:将起点放入队列,并设置其优先级为起点距离。 3. 主循环:从队列中取出当前距离最小的节点(通常是最小优先级的节点),然后更新其相邻节点的距离,如果通过当前节点到达更短,就更新这些节点的距离并将它们加入队列。 4. 遍历邻接节点:对于每个相邻节点,检查通过当前节点到达它的路径是否比之前记录的更短。如果是,更新并标记该节点为已访问。 5. 重复步骤3和4,直到队列为空或找到终点。如果队列为空且未访问到终点,说明找不到从起点到终点的路径。 ```java import java.util.*; class Node implements Comparable<Node> { int id; int distance; Node previous; public Node(int id) { this.id = id; this.distance = Integer.MAX_VALUE; } @Override public int compareTo(Node other) { return Integer.compare(this.distance, other.distance); } } public class Dijkstra { // 使用PriorityQueue存储节点 private PriorityQueue<Node> queue = new PriorityQueue<>(); // 图的邻接表或哈希映射 private Map<Integer, List<Node>> graph; public List<Node> dijkstra(int start) { // ... (初始化、添加起点到队列等) while (!queue.isEmpty()) { Node current = queue.poll(); // 取出距离最小的节点 // 更新未访问的邻居 for (Node neighbor : graph.get(current.id)) { int distanceToNeighbor = current.distance + neighbor.distance; if (distanceToNeighbor < neighbor.distance) { neighbor.distance = distanceToNeighbor; neighbor.previous = current; queue.offer(neighbor); } } } // 返回从起点到终点的路径,如果找到 return buildPath(start); } private List<Node> buildPath(int end) { List<Node> path = new ArrayList<>(); Node currentNode = endNode(end); while (currentNode != null) { path.add(currentNode); currentNode = currentNode.previous; } Collections.reverse(path); return path; } // ... (获取结束节点的方法,可能需要一个额外的哈希映射存储每个节点的结束标识) } ```
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值