【算法学习】带权有向图的最短路径问题——Dijkstra算法


【算法学习】带权有向图的最短路径问题——Dijkstra算法

实现过程参考视频内容:实现过程点我查看!

个人感觉这是我看过的教程中较容易理解的一个视频,我的算法也是根据这个写的,具体实现过程看视频!!

Dijkstra算法的核心就是松弛技术

具体实现代码,其中出现的MyQueue和MyStack是我自己实现的数据结构,ctrl+F换成自己的或者自带的即可

package IOTest.graph;

import IOTest.queue.MyQueue;
import IOTest.stack.MyStack;

@SuppressWarnings("all")
public class MyDijkstraShortestPath {
    public static void main(String[] args) {
        MyEdgeWeightedDigraph gragh = new MyEdgeWeightedDigraph(6);
        gragh.addEdge(new MyDirectedEdge(0,1,2));
        gragh.addEdge(new MyDirectedEdge(1,2,1));
        gragh.addEdge(new MyDirectedEdge(0,2,4));
        gragh.addEdge(new MyDirectedEdge(2,3,4));
        gragh.addEdge(new MyDirectedEdge(2,4,5));
        gragh.addEdge(new MyDirectedEdge(4,5,3));
        gragh.addEdge(new MyDirectedEdge(3,5,3));
        gragh.addEdge(new MyDirectedEdge(1,3,6));
        MyDijkstraShortestPath myDijkstraShortestPath = new MyDijkstraShortestPath(gragh,0);
        MyStack theShortestPath = myDijkstraShortestPath.getTheShortestPath(5);
        theShortestPath.forEach(item ->{
            System.out.print(item+"===>");
        });
    }

    /**
     * 从起点到某个结点的最短路径
     */
    private MyStack theShortestPath;

    /**
     * 记录某点的前一个点
     */
    private int[] frontPoint;

    /**
     * 其余各点到起点的距离
     */
    private double[] distance;

    /**
     * 记录某个顶点是否被标记为了最优结点
     */
    private boolean[] certain;

    /**
     * 待处理的图
     */
    private MyEdgeWeightedDigraph graph;

    public MyDijkstraShortestPath(MyEdgeWeightedDigraph graph,int start) {
        int V = graph.getV();
        this.distance = new double[V];
        this.certain = new boolean[V];
        this.frontPoint = new int[V];
        this.theShortestPath = new MyStack<>();
        this.graph = graph;

        for (int i = 0; i < distance.length; i++) {
            distance[i] = Double.MAX_VALUE;
        }
        distance[start] = 0.0;
        frontPoint[start] = start;

        visit(start);
    }

    private void visit(int v) {
        int min = findMin();
        if(min == distance.length){return;}
        certain[min] = true;
        MyQueue allNearEdges = graph.getAllNearEdges(min);
        for (MyDirectedEdge allNearEdge : allNearEdges) {
            int start = allNearEdge.getStart();
            int end = allNearEdge.getEnd();
            double weight = allNearEdge.getWeight();
            // 比较从起点经过当前顶点到达目标结点的距离与直接动起点到目标结点的距离
            // 如果中转的距离比直接到的距离小,则更新距离表,并把目标结点的前一个结点设置为当前结点
            if(distance[start]+weight