数据结构算法爬坑日记十九

Dijkstra算法

思路:将一个点作为出发点,基于广度优先进行遍历,将出发点到各个点的最短距离记录,在以出发点到各个点最
短距离的点进行遍历,查看经过该点到各个点的距离是否是最短距离,如果是就更新,循环此操作直到将所有的点
全部遍历

代码实现
//Dijkstra求解最短路径
public class Dijkstra {
    char[] vertexes;//顶点数组
    int[][] commons;//邻接矩阵
    int[] alreadyVertex;//被访问过的顶点 1 代表已访问
    int[] preVisited;//每个节点的前驱节点
    int[] dis;//出发点到各个顶点的最短路径
    final int N = 65525;//代表二点没连通

    public static void main(String[] args) {
        final int N = 65525;
        char[] vertexes = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] commons = new int[][]{
                {N, 5, 7, N, N, N, 2},
                {5, N, N, 9, N, N, 3},
                {7, N, N, N, 8, N, N},
                {N, 9, N, N, N, 4, N},
                {N, N, 8, N, N, 5, 4},
                {N, N, N, 4, 5, N, 6},
                {2, 3, N, N, 4, 6, N}
        };
        Dijkstra dijkstra = new Dijkstra();
        dijkstra.insGraph(vertexes, commons);
        dijkstra.insInfo(6);
        dijkstra.dijkstra();
    }

    //初始化原始图信息
    public void insGraph(char[] vertexes, int[][] commons) {
        this.vertexes = vertexes;
        this.commons = commons;
    }

    //index出发点
    public void insInfo(int index) {
        alreadyVertex = new int[vertexes.length];
        preVisited = new int[vertexes.length];
        dis = new int[vertexes.length];
        Arrays.fill(dis, N);
        dis[index] = 0;
        update(index);
    }

    //更新指定点到与之连通点的距离和前驱节点
    public void update(int index) {
        int len;//当前点到各个点的距离
        for (int i = 0; i < commons[index].length; i++) {
            //出发点经过当前点到各个点的距离
            len = dis[index] + commons[index][i];
            if (len < dis[i] && alreadyVertex[i] == 0) {
                //说明经过当前点比直接到各个点的距离更短并且点未被访问 更新前驱点和距离信息
                preVisited[i] = index;
                dis[i] = len;
            }
        }
        alreadyVertex[index] = 1;//当前点已被访问
    }

    //寻找下一个开始节点
    public int seekNext() {
        //出发点到各个点的最短距离和下一个开始节点的索引
        int min = N;
        int index = 0;
        for (int i = 0; i < vertexes.length - 1; i++) {
            if (alreadyVertex[i] == 0 && dis[i] < min) {
                //保存最小值和对应顶点索引
                min = dis[i];
                index = i;
            }
        }
        return index;
    }

    //dijkstra算法实现
    public void dijkstra() {
        int index;
        for (int i = 0; i < vertexes.length - 1; i++) {
            index = seekNext();
            update(index);
        }
        //显示结果
        System.out.println("各个点的前驱节点 " + Arrays.toString(preVisited));
        System.out.println("出发点到各个点的最短路径 " + Arrays.toString(dis));
    }
}

Floyd算法

求最短路径与Dijkstra算法不同,一次求出所有顶点为出发点到各个顶点的最短路径,分别以各个顶点为中间节
点,比较过此中间节点的两点与两点直连的距离的大小并进行更新直到循环全部顶点得到结果便是各个顶点的最
短路径

算法实现
//floyd算法求最短路径
public class Floyd {
    char[] vertexes;
    int[][] pre;
    int[][] dis;//存放各点开始到各点的最短距离
    static final int INT = 65535;

    public static void main(String[] args) {
        char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] common = new int[][]{
                {0, 5, 7, INT, INT, INT, 2},
                {5, 0, INT, 9, INT, INT, 3},
                {7, INT, 0, INT, 8, INT, INT},
                {INT, 9, INT, 0, INT, 4, INT},
                {INT, INT, 8, INT, 0, 5, 4},
                {INT, INT, INT, 4, 5, 0, 6},
                {2, 3, INT, INT, 4, 6, 0}
        };
        Floyd floyd = new Floyd();
        floyd.insInfo(vertex, common);
        floyd.floyd();
    }

    //初始化信息
    public void insInfo(char[] vertexes, int[][] commons) {
        this.vertexes = vertexes;
        dis = commons;
        pre = new int[vertexes.length][vertexes.length];
        for (int i = 0; i < vertexes.length; i++) {
            Arrays.fill(pre[i], i);
        }

    }

    //floyd算法实现
    public void floyd() {
        int len;
        for (int k = 0; k < vertexes.length; k++) {
            for (int i = 0; i < vertexes.length; i++) {
                for (int j = 0; j < vertexes.length; j++) {
                    //比较两点直连距离与过节点相连的距离大小
                    len = dis[i][k] + dis[k][j];
                    if (len < dis[i][j]) {
                        //更新最短距离和前驱节点
                        dis[i][j] = len;
                        pre[i][j] = pre[k][j];
                    }
                }
            }
        }
        for (int[] di : dis) {
            System.out.println("各点距离 " + Arrays.toString(di));
        }
        for (int[] ints : pre) {
            System.out.println("前驱节点 " + Arrays.toString(ints));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值