(Dijkstra)迪杰斯特拉算法

 

/*
    迪杰斯特拉算法  邻接表
 */
public class Dijkstra {

    char[] vertex;  //顶点

    List<Pair>[] lists; //邻接表

    boolean[] visited; //判断此顶点是否已经被标记

    int N; //存储顶点的个数

    int[] dist; //记录源到其余顶点最短距离

    int[] pre;  //记录每个结点最短路径中的前驱结点

    public Dijkstra(char[] nums){
        this.vertex = Arrays.copyOf(nums,nums.length); //初始化顶点
        lists = new List[nums.length];
        visited = new boolean[nums.length];
        this.N = nums.length;
        //初始化邻接表
        for(int i = 0;i<lists.length;i++){
            lists[i] = new ArrayList<>();
        }
        lists[0].add(new Pair(1,5));
        lists[0].add(new Pair(5,2));
        lists[0].add(new Pair(2,4));

        lists[1].add(new Pair(0,5));
        lists[1].add(new Pair(5,1));
        lists[1].add(new Pair(4,3));

        lists[2].add(new Pair(0,4));

        lists[3].add(new Pair(5,4));
        lists[3].add(new Pair(4,3));

        lists[4].add(new Pair(1,3));
        lists[4].add(new Pair(5,2));
        lists[4].add(new Pair(3,3));

        lists[5].add(new Pair(0,2));
        lists[5].add(new Pair(1,1));
        lists[5].add(new Pair(4,2));
        lists[5].add(new Pair(3,4));
    }

    public void Dijkstra(int origin){
        pre  = new int[N];  //表示每个顶点在最短路径中的的前驱顶点
        for(int i =0;i<N;i++){  //初始化
            pre[i] =-1;
        }
        dist = new int[N]; //表示源点到其余顶点的最短距离
        for(int i = 0;i<N;i++){
            if(i==origin){
                dist[0] = 0; //自身到自己的距离为0
            }else{
                dist[i] = Integer.MAX_VALUE; //其余初始为默认值
            }
        }
        visited[origin] = true;  //开始的顶点已经被标记
        List<Pair> list = lists[origin]; //获取起始顶点直接相连的其他顶点
        for(int i = 0;i<list.size();i++){
            Pair pair = list.get(i);
            dist[pair.getIndex()] = pair.getWeight();  //更新最短距离
            pre[pair.getIndex()] = origin; //更新前驱顶点表
        }
        //开始循环
        for(int i = 1;i<N;i++){
            //找出dist中除了已经访问过的顶点的最小距离顶点
            int minDist = Integer.MAX_VALUE;
            int minIndex = -1;
            for(int j = 0;j<dist.length;j++){ //遍历dist表
                if(!visited[j]&&dist[j]<minDist){  //必须是在未被标记的顶点中选择
                    minDist = dist[j];
                    minIndex  =j;
                }
            }
            if(minIndex == -1){ //没有找到小于Integer.MAX_VALUE的距离,说明开始的源顶点与其余的顶点都没有相连
                return;
            }
            //开始更新距离和前驱顶点
            //拿到minIndex顶点的连接的顶点
            List<Pair> list1 = lists[minIndex];
            //标记minIndex顶点
            visited[minIndex] = true;
            //开始遍历
            for(int j = 0;j<list1.size();j++){
                Pair pair = list1.get(j);
                int newDist = minDist + pair.weight; //记录经过该节点到目的结点的距离
                if(!visited[pair.getIndex()]&&newDist<dist[pair.getIndex()]){  //必须是在没有被标记的顶点,然后比较
                    //更新距离和前驱顶点
                    dist[pair.getIndex()] = newDist;
                    pre[pair.getIndex()] = minIndex;
                }
            }
        }
    }

    //展示最短距离
    public  void showMinDist(){
        System.out.println(Arrays.toString(dist));
    }

    //打印路径
    public void getPath(int startIndex,int endIndex){
        Stack<Character> stack = new Stack<>();
        stack.push(vertex[endIndex]);
        int front = pre[endIndex];
        while(front!=startIndex){
            stack.push(vertex[front]);
            front = pre[front];
        }
        stack.push(vertex[front]);
        while(!stack.isEmpty()){
            System.out.print(stack.pop()+"-->");
        }
    }

    //Pair对  index:表示顶点在vertex中的索引,weight表示权重
    public static class Pair{
        int index;
        int weight;
        public Pair(int index,int weight){
            this.index = index;
            this.weight = weight;
        }
        public int getIndex(){
            return this.index;
        }
        public int getWeight(){
            return this.weight;
        }
    }

    public static void main(String[] args) {
        Dijkstra dijkstra = new Dijkstra(new char[]{'A', 'E', 'F', 'P', 'H', 'G'});
        dijkstra.Dijkstra(1);
        dijkstra.showMinDist();
        int endIndex = 3;
        dijkstra.getPath(1,3);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值