实现JAVA结合前向量实现Dijkstra

Dijkstra思想:

使用一个dist数组保存到所有其它点的距离;

给定任意一个起点,这个点形成一个集合,这个集合内的所有点,都知道从起点到它的最短距离,对于其他点暂时还不知道;我们需要通过贪心策略,不断扩大这个集合,最终得到到所有点的最短距离。

 选取距离表中【不在最短路径集合内】的最短距离(还没有使用过的点),就可以得到距离当前集合内最近的一个点,通过这个点贪心的松弛其他点到集合的距离,最后直到所有点都加入到最短路径集合内部,结束。

package com.yxs.graph1;

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;

public class Dijkstra {
	static int MAXN = 105;
	static class Edge{
		int to;
		int w;
		int next;
		{
			to = 0;
			w = 0;
			next = 0;
		}
	}
	static int[] head = new int[MAXN];
	static Edge[] edge = new Edge[MAXN];
	static int len = 1;
	static void add(int from, int to, int w) {
		edge[len] = new Edge();
		edge[len].to = to;
		edge[len].w = w;
		edge[len].next = head[from];
		head[from] = len++;
	}
	
	static boolean[] vis = new boolean[MAXN];
	static int[] dist = new int[MAXN];
	static int[] path = new int[MAXN];
	static final int INF = 0x3f3f3f3f;
	static {
		Arrays.fill(vis, false);
		Arrays.fill(dist, INF);
		Arrays.fill(path, 0);
	}
	
	static void dijkstra(int n) {
		dist[1] = 0;
		for(int i = 1;i <= n;i++) {
			int ind = 0;//找一个点距离i最近的点,记录序号			
			for(int j = 1;j <= n;j++) {
				if(!vis[j] && (ind == 0 || dist[j] < dist[ind])) {
					ind = j;
				}
			}
			vis[ind] = true;//找到目前已知的能够到最短距离的点(且没有被调整过)
			for(int j = head[ind];j != 0;j = edge[j].next) {//通过目前知道距离最近的点,调整能够通过这个点到达的所有点,缩短距离。
				if(dist[edge[j].to] > dist[ind] + edge[j].w) {
					dist[edge[j].to] = dist[ind] + edge[j].w;
					path[edge[j].to] = ind;//记录路径
				}
			}
		}
		if(dist[n] == INF) {
			System.out.println("到终点的最短路径不存在");
		}else {
			System.out.println("最短路径的距离为:" + dist[n] + "   具体路径如下:");
			Stack<Integer> stack = new Stack<>();
			for(int i = n;i != 0; i = path[i]) {
				stack.add(i);
			}
			while(!stack.isEmpty()) {
				System.out.print(stack.peek() + "--->");
				stack.pop();
			}
			System.out.println("END");
		}
	}
	
	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedInputStream(System.in));
		int n = in.nextInt();
		int e = in.nextInt();
		for(int i = 1;i <= e;i++) {
			int from = in.nextInt();
			int to = in.nextInt();
			int w = in.nextInt();
			add(from, to, w);
		}
		dijkstra(n);
	}
	
/*
6 8
1 6 100
1 5 30
1 3 10
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60


*/
	
}

 

这里写图片描述

/* * 基于数组的向量实现 */ package dsa; public class Vector_Array implements Vector { private final int N = 1024;//数组的容量 private int n = 0;//向量的实际规模 private Object[] A;//对象数组 //构造函数 public Vector_Array() { A = new Object[N]; n = 0; } //返回向量中元素数目 public int getSize() { return n; } //判断向量是否为空 public boolean isEmpty() { return (0 == n) ? true : false; } //取秩为r的元素 public Object getAtRank(int r)//O(1) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); return A[r]; } //将秩为r的元素替换为obj public Object replaceAtRank(int r, Object obj) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); Object bak = A[r]; A[r] = obj; return bak; } //插入obj,作为秩为r的元素;返回该元素 public Object insertAtRank(int r, Object obj) throws ExceptionBoundaryViolation { if (0 > r || r > n) throw new ExceptionBoundaryViolation("意外:秩越界"); if (n >= N) throw new ExceptionBoundaryViolation("意外:数组溢出"); for (int i=n; i>r; i--) A[i] = A[i-1];//后续元素顺次后移 A[r] = obj;//插入 n++;//更新当规模 return obj; } //删除秩为r的元素 public Object removeAtRank(int r) throws ExceptionBoundaryViolation { if (0 > r || r >= n) throw new ExceptionBoundaryViolation("意外:秩越界"); Object bak = A[r]; for (int i=r; i<n; i++) A[i] = A[i+1];//后续元素顺次移 n--;//更新当规模 return bak; } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值