Dijkstra算法的优化-实现代码

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); #回溯输出
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值