加权有向图实现
我们实现两个类,权重边类和有向图类。有向图类中组合权重边类来实现加权有向图。
权重边类实现:
public class DirectedEdge {
private int v;
private int w;
private double weight;
public DirectedEdge(int v,int w,double weight) {
this.v = v;this.w = w;this.weight = weight;
}
public double weight(){ return weight; }
public int form(){ return v; }
public int to(){ return w; }
public String toString(){ return String.format("%d->%d %.2f", v,w,weight); }
}
加权有向图实现:
public class EdgeWeightedDigraph {
private int V;//顶点数
private int E;//边数
private Bag<DirectedEdge>[] adj;//邻接表
public EdgeWeightedDigraph(int V) {
this.V = V;
this.E = 0;
adj = (Bag<DirectedEdge>[]) new Bag[V];
for(int v=0;v< V;v++) {
adj[v] = new Bag<DirectedEdge>();
}
}
public int V() {return V;}
public int E() {return E;}
public void addEdge(DirectedEdge e) {
adj[e.form()].add(e);
E++;
}
//从v指出的边
public Iterable<DirectedEdge> adj(int v){return adj[v];}
//该有向图中所有的边
public Iterable<DirectedEdge> edges(){
Bag<DirectedEdge> bag = new Bag<DirectedEdge>();
for(int v = 0; v<V; v++)
for(DirectedEdge e : adj[v])
bag.add(e);
return bag;
}
}
Dijkstra算法
Dijkstra算法可以解决边的权重非负的最短路径问题,无法判断含负权边的图的最短路径,但Bellman-Ford算法可以。
边的松弛:
在实现Dijkstra算法之前,必须先了解边的松弛:松弛边v->w意味着检查从s到w的最短路径是否是先从s到v,再从v到w。如果是