dijkstra算法(单源最短路径) Java实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AivenZhong/article/details/88904877

用例图:
在这里插入图片描述

用ArrayList实现的邻接表图,每个结点有个动态列表记录这个结点的邻边数据Edge包括(指向的下一个结点,边权)基于此图写了一个dijk算法。

dijk的主要流程:
花销表int[] costs:记录从源点到各花销的最短路径。
访问表boolean[] vis:表示哪些结点可以走。
1.costs[源点] = 0,其他点的cost设置为Integer.MAX_VALUE
2.vis所有值为false
3.从costs中找最小值minCost,顺便找到对应的结点minNode。把对应的结点的vis标true, vis[minNode] = true,计数加一。
4.从这个最小结点出发找未被访问的结点node的邻边cost,如果minCost + cost < costs[node]更新costs[node].
5.重复3 4 步骤,直到计数等于结点数,结束。

import java.util.ArrayList;

public class dij {
	static int len = 7;
	static int[] costs = new int[len];
	static int[] parents = new int[len];

	public static void main(String[] args) {
		int[][] datas = { { 1, 0, 8 }, { 1, 2, 5 }, { 1, 3, 10 }, { 1, 6, 9 }, { 2, 0, 1 }, { 0, 6, 2 }, { 3, 6, 5 },
				{ 3, 4, 8 }, { 0, 5, 4 }, { 5, 6, 7 }, { 5, 3, 8 }, { 5, 4, 5 } };

		// 邻接表
		ArrayList<Edge>[] graph = new ArrayList[len];
		for (int i = 0; i < len; i++) {
			graph[i] = new ArrayList<>();
		}
		for (int i = 0; i < datas.length; i++) {
			int u = datas[i][0];
			int v = datas[i][1];
			int c = datas[i][2];
			graph[u].add(new Edge(v, c));
			graph[v].add(new Edge(u, c));
		}

		dijk(1, graph);
		System.out.println("Costs:");
		for (int i : costs) {
			System.out.print(i + " ");
		}
		System.out.println("\nParents:");
		for (int i : parents) {
			System.out.print(i + " ");
		}
	}

	public static void dijk(int start, ArrayList<Edge>[] graph) {
		boolean[] vis = new boolean[len];

		for (int i = 0; i < len; i++)
			costs[i] = Integer.MAX_VALUE;
		costs[start] = 0;

		parents[start] = -1;

		int count = 0;
		while (count < len) {
			// 先在costs中找最小花销的未确定的边
			int minNode = -1;
			int minCost = Integer.MAX_VALUE;
			for (int i = 0; i < len; i++) {
				if (!vis[i] && costs[i] < minCost) {
					minCost = costs[i];
					minNode = i;
				}
			}
			vis[minNode] = true;
			count++;

			// 再从这个最小边的结点出发找未被访问的结点的边,更新costs
			ArrayList<Edge> nextEdge = graph[minNode];
			for (Edge edge : nextEdge) {
				int node = edge.next;
				int cost = edge.cost;
				if (!vis[node] && minCost + cost < costs[node]) {
					costs[node] = minCost + cost;
					parents[node] = minNode;
				}
			}
		}
	}

}

class Edge {
	int next;
	int cost;

	Edge() {
	}

	Edge(int next, int cost) {
		this.next = next;
		this.cost = cost;
	}
}


// 运行结果
// Costs:
// 6 0 5 10 15 10 8
// Parents:
// 2 -1 1 1 5 0 0

猜你喜欢

转载自blog.csdn.net/AivenZhong/article/details/88904877