Dijkstra算法——java实现

面试时遇到Dijkstra算法,这个算法我是知道的,但是没具体写过,所以答题比较慢,抽时间实现了下这个算法。

Dijkstra算法基本思路:

该算法的基本思路是这样的,从起始点开始,将未访问过的相邻节点加入一个优先队列,类似于广度优先算法,然后从该队列中取出节点考虑:

对于单个节点,找出其所有相邻边,对于其邻接节点,计算总长度,如果该邻接节点的长度大于从该节点的长度,则更新路径为该节点。

具体代码如下:

package src.arithmetic;


import java.util.*;
import java.util.Map.Entry;

/**
 * Dijkstra算法
 */
public class Dijkstra
{
    public static class Node
    {
        public int nodeId;//节点标识
        public List<Edge> adjEdge;//相邻边边
        public Node(int nodeId, List<Edge> adjEdge) {
            this.nodeId = nodeId;
            this.adjEdge = adjEdge;
        }
    }

    /**
     * 发出边
     */
    public static class Edge
    {
        public int endNode;//终止节点
        public int weigth;//边的权重
        public Edge(int endNode,int weigth)
        {
            this.endNode=endNode;
            this.weigth=weigth;
        }
    }

    Map<Integer,Node> graph;//图
    private Node startNode;//起始点
    private Map<Integer,Integer> distTo;//记录当前最短距离
    private Queue<Node> pq;//优先队列

    public Dijkstra(Map graph,Node startNode)
    {
        this.graph=graph;
        this.startNode=startNode;
        distTo=new HashMap<>();
        pq=new LinkedList<>();
    }

    /**
     * Dijkstra算法主体
     */
    public void gogogo()
    {
        //从起始点开始
        pq.offer(startNode);
        distTo.put(startNode.nodeId,0);
        while(!pq.isEmpty())
        {
            Node tempNode = pq.peek();
            pq.remove();
            int curLen=distTo.get(tempNode.nodeId);
            //对于所有相邻边
            for (Edge nextEdge:tempNode.adjEdge)
            {
                //如果还没被访问过,则暂时设置为从当前节点到此为最短距离。同时将该点记录到pq(广度优先)
                if(distTo.get(nextEdge.endNode) == null)
                {
                    pq.offer(graph.get(nextEdge.endNode));
                    distTo.put(nextEdge.endNode, curLen + nextEdge.weigth);
                }
                //如果当前节点被访问过,但不是最短路径,则更新。
                else if(distTo.get(nextEdge.endNode) > curLen + nextEdge.weigth)
                {
                    distTo.put(nextEdge.endNode, curLen + nextEdge.weigth);
                }
            }
        }
        System.out.println("从节点:" + startNode.nodeId +"开始,到达其他节点的最短距离分别为:");
        for(Entry<Integer,Integer> entry : distTo.entrySet())
        {
            System.out.println("到节点: " + entry.getKey() + "距离为 : " + entry.getValue());
        }

    }
    //测试用例
    public static void main(String[] args)
    {
        Map<Integer,Node> testGraph = new HashMap<>();
        Edge e04 = new Edge(4,38);
        Edge e02 = new Edge(2, 26);
        Edge e27 = new Edge(7, 34);
        Edge e47 = new Edge(7, 37);
        Edge e45 = new Edge(5, 35);
        Edge e54 = new Edge(4, 35);
        Edge e57 = new Edge(7, 28);
        Edge e75 = new Edge(5, 28);
        Edge e51 = new Edge(1, 32);
        Edge e73 = new Edge(3, 39);
        Edge e13 = new Edge(3, 29);
        Edge e62 = new Edge(2, 40);
        Edge e36 = new Edge(6, 52);
        Edge e60 = new Edge(0, 58);
        Edge e64 = new Edge(2, 93);
        List<Edge> l0 = new LinkedList<>();
        l0.add(e02);
        l0.add(e04);
        List<Edge> l1 = new LinkedList<>();
        l1.add(e13);
        List<Edge> l2 = new LinkedList<>();
        l2.add(e27);
        List<Edge> l3 = new LinkedList<>();
        l3.add(e36);
        List<Edge> l4 = new LinkedList<>();
        l4.add(e45);
        l4.add(e47);
        List<Edge> l5 = new LinkedList<>();
        l5.add(e51);
        l5.add(e54);
        l5.add(e57);
        List<Edge> l6 = new LinkedList<>();
        l6.add(e60);
        l6.add(e62);
        l6.add(e64);
        List<Edge> l7 = new LinkedList<>();
        l7.add(e73);
        l7.add(e75);
        Node n0= new Node(0,l0);
        Node n1= new Node(1,l1);
        Node n2= new Node(2,l2);
        Node n3= new Node(3,l3);
        Node n4= new Node(4,l4);
        Node n5= new Node(5,l5);
        Node n6= new Node(6,l6);
        Node n7= new Node(7,l7);
        testGraph.put(0,n0);
        testGraph.put(1,n1);
        testGraph.put(2,n2);
        testGraph.put(3,n3);
        testGraph.put(4,n4);
        testGraph.put(5,n5);
        testGraph.put(6,n6);
        testGraph.put(7,n7);
        Dijkstra dijkstra =new Dijkstra(testGraph,n0);
        dijkstra.gogogo();


    }

}

猜你喜欢

转载自blog.csdn.net/Strom72/article/details/82531592