Dijkstra算法的优化-实现代码
注:代码转自优秀的公众号程序员小灰,码住只是为了方便自己以后看~大家有兴趣的还是去看原文讲解哦!
如何求得图中最短路径的详细节点,而不仅仅是距离?
简单思想
简单来说就是在原始的距离表基础上再加上一个【前置顶点表],这个表存储了从起点到其他顶点的最短距离的前置顶点下标。然后维护[前置顶点表]和[距离表]的元素一一对应。最后使用回溯法,自后向前回溯将前置顶点表“翻译”成图的最短路径。
实现代码
这里就不码initGraph()函数啦。
#图的顶点
private static class Vertex{
String data;
Vertex(String data){
this.data = data;
}
}
#图的边
private static class Edge{
int index;
int weight;
Edge(int index, int weight){
this.index = index;
this.weigh = weigh;
}
}
#图
private static class Graph{
private Vertex[] vertexes;
private LinkedList<Edge> adj[];
Graph(int size){
vertexes = new Vertex[size];
adj = new LinkedList[size];
for(int i=0;i<adj.length;i++){
adj[i] = new LinkedList<edg>();
}
}
}
#回溯输出前置顶点表
private static void printPrevs(vertex[] vertexes, int[] prev,int i){
if(i>0){
printPrevs(vertexes,prev,prev[i]);
}
system.out.println(vertexes[i].data);
}
# Dijkstra最短路径算法
public static int[] dijkstra(Graph graph, int startIndex){
#图的顶点数
int size = graph.vertexes.length;
#创建距离表,存储从起点到每一个顶点的临时距离
int[] distances - new int[size];
#创建前置顶点表,存储从起点到每一个顶点的已知最短路径的前置节点
int[] prevs = new int[size];
#记录顶点遍历状态
boolean[] access = new boolean[size];
#初始化最短路径表,到达每个顶点的路径代价默认为无穷大
for(int i=0;i<size;i++){
distances[i] = Integer.MAX_VALUE;
}
#遍历起点,刷新距离表
access[0] = true;
List<Edge> edgesFromStart = graph.adj[startIndex];
for(Edge edge:edgesFromStart){
distances[edge.index] = edge.weight;
prevs[edge.index] = 0;
}
#主循环,重复 遍历最短距离顶点和刷新距离表 的操作
for(int i=1;i<size;i++){
#寻找最短距离顶点
int minDistanceFromStart = Integer.MAX_VALUE;
int minDistanceIndex = -1;
for(int j=1;j<size;j++){
if(!access[j] && distances[j] < minDistanceFromStart){
minDistanceFromStart = distance[j];
minDistanceIndex = j;
}
}
if(minDistanceIndex == -1){
break;
}
#遍历顶点,刷新距离表
access[minDistanceIndex] = true;
for(Edge edge:graph.minDistanceIndex){
if(access[edge.index]){
continue;
}
int weight = edge.weight;
int preDistance = distances[edge.index];
if(weight != Integer.MAX_VALUE && (minDistanceFromStart + weight< preDistance)){
distances[edge.index] = minDistanceFromStart + weight;
prevs = minDistanceIndex;
}
}
}
return prevs;
}
#main函数
public static void main(String[] args){
Graph graph = new Graph(7);
initGragh(graph);
int[] prevs = dijkstra(graph,0);
printPrevs(graph.vertexes,prevs,graph.vertexes.length-1); #回溯输出
}