版权声明:本文为博主原创文章,未经博主允许不得转载。 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