Dijkstra算法描述

一. 能解决的问题及思想

找到从一个顶点到其他顶点的最短距离,是基于贪心思想以源点为中心层层向外扩散。


二. 算法的实现

结束条件:所有点都加入S集合(S集合开始为空)

   dist 向量,dist[i] 表示V0到Vi 的距离

1. 初始化dist 向量,将V0加入S集合

2. 找特殊点(该点不在S集合,且源点通过S中的0到多个点可以到达该点),

    将该点加入到S集合,更新dist 集合

### Dijkstra算法的基本概念 Dijkstra算法是一种用于解决单源最短路径问题的经典贪心算法,其核心目标是从给定的起点出发计算到其他所有节点的最短路径长度。该算法假设所有的边权均为非负数[^1]。 #### 算法的核心思想 Dijkstra算法通过逐步扩展已知最短路径集合的方式工作。它维护了一个优先队列(或数组),记录当前从起始点到各节点的距离估计值,并不断更新这些距离直到找到真正的最短路径[^5]。 --- ### 实现方式 #### 基本流程 以下是Dijkstra算法的主要实现步骤: 1. 初始化:设定起点 `v0` 的距离为 0,其余所有节点的距离设为无穷大(表示未知)。创建一个布尔型数组标记哪些节点已被访问过。 2. 找到尚未被处理且具有最小临时距离的节点作为当前节点。 3. 对于当前节点的所有邻居节点,尝试更新它们的距离。如果发现更短的路径,则更新对应的距离值。 4. 将当前节点标记为已处理状态。 5. 重复上述操作直至所有可到达的节点都被处理完毕或者找到了特定的目标节点为止。 此过程中涉及的关键数据结构包括: - **距离数组** (`dist[]`):保存从起点到每个节点的最佳已知距离; - **访问标志位数组** (`vis[]`):用来跟踪某个节点是否已经被最终确认为其最短路径上的成员; - (可选)**前驱指针/父结点信息**:帮助重建实际路径而非仅仅获取总成本。 #### Java代码示例 下面给出一段基于邻接表形式存储图结构下的标准Java版本实现[^2]: ```java import java.util.*; public class Dijkstra { static final int INF = Integer.MAX_VALUE; public static void dijkstra(List<List<Edge>> adj, int n, int start){ PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(node -> node.distance)); int[] dist = new int[n]; Arrays.fill(dist, INF); boolean[] visited = new boolean[n]; dist[start]=0; pq.add(new Node(start, 0)); while(!pq.isEmpty()){ Node u=pq.poll(); if(visited[u.vertex])continue; visited[u.vertex]=true; for (Edge e : adj.get(u.vertex)){ if (!visited[e.to] && dist[e.to]>u.distance+e.weight){ dist[e.to]=u.distance+e.weight; pq.add(new Node(e.to,dist[e.to])); } } } System.out.println(Arrays.toString(dist)); // 输出结果 } static class Edge{ int to, weight; public Edge(int t,int w){to=t;weight=w;} } static class Node implements Comparable<Node>{ int vertex,distance; public Node(int v,int d){vertex=v;distance=d;} @Override public int compareTo(Node o) {return this.distance-o.distance;} } public static void main(String args[]){ List<List<Edge>> graph=new ArrayList<>(); int nodes=6; for(int i=0;i<nodes;i++)graph.add(new ArrayList<>()); addEdge(graph,0,2,7);addEdge(graph,0,1,9);addEdge(graph,0,5,14); addEdge(graph,1,2,10);addEdge(graph,1,3,12);addEdge(graph,2,3,8); addEdge(graph,2,5,15);addEdge(graph,3,4,6);addEdge(graph,4,5,9); dijkstra(graph,nodes,0); } private static void addEdge(List<List<Edge>> g,int from,int to,int wt){ g.get(from).add(new Edge(to,wt)); } } ``` #### C++代码示例 对于C++,可以利用STL中的vector和priority_queue完成相似功能[^3]: ```cpp #include <bits/stdc++.h> using namespace std; const long long INF = LLONG_MAX / 2; struct Edge { int to; long long cost; }; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); int V,E,start; cin >> V >> E >> start; vector<vector<Edge>> G(V+1); for(int i=0;i<E;++i){ int a,b,cost; cin>>a>>b>>cost; G[a].push_back({b,(long long)(cost)}); } priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<>> PQ; vector<long long> distance(V+1,INF); distance[start]=0; PQ.emplace(0,start); while(!PQ.empty()){ auto [currentDist,u]=PQ.top();PQ.pop(); if(distance[u]<currentDist)continue; for(auto &[v,w]:G[u]){ if(currentDist+w<distance[v]){ distance[v]=currentDist+w; PQ.emplace(distance[v],v); } } } for(int i=1;i<=V;i++)cout<<((distance[i]==INF)?-1:distance[i])<<"\n"; } ``` --- ### 总结 综上所述,Dijkstra算法是一个非常重要的工具,在许多领域都有广泛的应用价值。无论是理论分析还是工程实践当中,掌握好它的原理以及高效编码技巧都是非常必要的[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值