数据结构与算法(图的最短路径与拓扑排序)

数据结构与算法(图的最短路径与拓扑排序)

首语

图的最短路径

  • 从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径,解决最短路径通常有Dijkstra算法。

迪杰斯特拉算法(Dijkstra)

  • 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

代码实现

    private final static int MAXVEX = 9;
    private final static int MAXWEIGHT = 65535;
    private int[] shortTablePath = new int[MAXVEX];//记录的是v0到某顶点的最短路径和

    /**
     * 获取一个图的最短路径
     *
     * @param graph
     */
    public void shorttestPathDijstra(Graph graph) {
        int min;
        int k = 0;//记录下标
        boolean[] isgetPath = new boolean[MAXVEX];
        for (int v = 0; v < graph.getVertexSize(); v++) {
            shortTablePath[v] = graph.getMatrix()[0][v];//获取v0这一行的权值数组
        }
        shortTablePath[0] = 0;
        isgetPath[0] = true;
        for (int v = 1; v < graph.getVertexSize(); v++) {
            min = MAXWEIGHT;
            for (int w = 0; w < graph.getVertexSize(); w++) {
                if (!isgetPath[w] && shortTablePath[w] < min) {
                    k = w;
                    min = shortTablePath[w];
                }

            }
            isgetPath[k] = true;
            for (int j = 0; j < graph.getVertexSize(); j++) {
                if (!isgetPath[j] && (min + graph.getMatrix()[k][j] < shortTablePath[j])) {
                    shortTablePath[j] = min + graph.getMatrix()[k][j];
                }
            }
        }
        for (int i = 0; i < shortTablePath.length; i++) {
            System.out.println("V0到V" + i + "的最短路径为:" + shortTablePath[i]+"\n");
        }
    }

拓扑排序

  • 在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称为AOV网(Activity On Vertex Network)。
  • 设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,·········,Vn,满足若从顶点Vi到Vj有一条路径,则在顶点序列中顶点Vi必在Vj之前。则我们称这样的顶点序列为一个拓扑序列。

代码实现


    public int numVertexes;
    private VertexNode[] adjList;//邻接顶点的一维数组
    public DnGraphToplogic(int numVertexes){
        this.numVertexes=numVertexes;
    }

    //边表顶点
    class EdgeNode{
        private int adjVert;
        private EdgeNode next;
        private int weight;
        public EdgeNode(int adjVert){
            this.adjVert=adjVert;
        }
    }

    //邻接顶点
    class VertexNode{
        private int in;//入度
        private String data;
        private EdgeNode firstEdge;

        public VertexNode(int in,String data){
            this.in=in;
            this.data=data;
        }
    }

    /**
     * 拓扑排序
     */
    private void topologicalSort() throws Exception {
        Stack<Integer> stack = new Stack<>();
        int count=0;
        int k=0;
        for (int i = 0; i < numVertexes; i++) {
            if (adjList[i].in==0){
                stack.push(i);
            }
        }
        while (!stack.isEmpty()){
            int pop=stack.pop();
            System.out.println("顶点"+adjList[pop].data);
            count++;
            for(EdgeNode node=adjList[pop].firstEdge;node!=null;node=node.next){
                k=node.adjVert;//下标
                if (--adjList[k].in==0){
                    stack.push(k);//入度为0,入栈
                }
            }
        }
        if (count<numVertexes){
            throw new Exception("拓扑排序失败!!!");
        }
    }

    private void createGraph(){
        VertexNode node0 = new VertexNode(0,"v0");
        VertexNode node1 = new VertexNode(0,"v1");
        VertexNode node2 = new VertexNode(2,"v2");
        VertexNode node3 = new VertexNode(0,"v3");
        VertexNode node4 = new VertexNode(2,"v4");
        VertexNode node5 = new VertexNode(3,"v5");
        VertexNode node6 = new VertexNode(1,"v6");
        VertexNode node7 = new VertexNode(2,"v7");
        VertexNode node8 = new VertexNode(2,"v8");
        VertexNode node9 = new VertexNode(1,"v9");
        VertexNode node10 = new VertexNode(1,"v10");
        VertexNode node11 = new VertexNode(2,"v11");
        VertexNode node12 = new VertexNode(1,"v12");
        VertexNode node13 = new VertexNode(2,"v13");
        adjList = new VertexNode[numVertexes];
        adjList[0] =node0;
        adjList[1] =node1;
        adjList[2] =node2;
        adjList[3] =node3;
        adjList[4] =node4;
        adjList[5] =node5;
        adjList[6] =node6;
        adjList[7] =node7;
        adjList[8] =node8;
        adjList[9] =node9;
        adjList[10] =node10;
        adjList[11] =node11;
        adjList[12] =node12;
        adjList[13] =node13;
        node0.firstEdge = new EdgeNode(11);node0.firstEdge.next = new EdgeNode(5);node0.firstEdge.next.next = new EdgeNode(4);
        node1.firstEdge = new EdgeNode(8);node1.firstEdge.next = new EdgeNode(4);node1.firstEdge.next.next = new EdgeNode(2);
        node2.firstEdge = new EdgeNode(9);node2.firstEdge.next = new EdgeNode(6);node2.firstEdge.next.next = new EdgeNode(5);
        node3.firstEdge = new EdgeNode(13);node3.firstEdge.next = new EdgeNode(2);
        node4.firstEdge = new EdgeNode(7);
        node5.firstEdge = new EdgeNode(12);node5.firstEdge.next = new EdgeNode(8);
        node6.firstEdge = new EdgeNode(5);
        node8.firstEdge = new EdgeNode(7);
        node9.firstEdge = new EdgeNode(11);node9.firstEdge.next = new EdgeNode(10);
        node10.firstEdge = new EdgeNode(13);
        node12.firstEdge = new EdgeNode(9);
    }

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.yanghujun.com/archives/dijkstra

Buy me a cup of coffee ☕.