1.加权无向图
加权无向图是一种为每条边关联一个权重值或是成本的图模型。这种图能够自然地表示许多应用。在一副航空图 中,边表示航线,权值则可以表示距离或是费用。在一副电路图中,边表示导线,权值则可能表示导线的长度即成 本,或是信号通过这条先所需的时间。此时我们很容易就能想到,最小成本的问题,例如,从西安飞纽约,怎样飞 才能使时间成本最低或者是金钱成本最低?
边的实现:
package 图;public class Edge implements Comparable<Edge> {private final int v;//顶点一private final int w;//顶点二private final double weight;//当前边的权重//通过顶点v和w,以及权重weight值构造一个边对象public Edge(int v, int w, double weight) {this.v = v;this.w = w;this.weight = weight;}//获取边的权重值public double weight() {return weight;}//获取边上的一个点public int either() {return v;}//获取边上除了顶点vertex外的另外一个顶点public int other(int vertex) {if (vertex == v) {//如果传入的顶点vertext是v,则返回另外一个顶点wreturn w;} else {//如果传入的顶点vertext不是v,则返回v即可return v;}}@Overridepublic int compareTo(Edge that) {int cmp;if (this.weight() > that.weight()) {//如果当前边的权重大于参数边that的权重,返回1cmp = 1;} else if (this.weight() < that.weight()) {//如果当前边的权重小于参数边that的权重,返回-1cmp = -1;} else {//如果当前边的权重等于参数边that的权重,返回0cmp = 0;}return cmp;}}
加权无向图的实现:
package 图;import 线性表.Queue;public class EdgeWeightedGraph {//顶点总数private final int V;//边的总数private int E;//邻接表private Queue<Edge>[] adj;//创建一个含有V个顶点的空加权无向图public EdgeWeightedGraph(int V) {//初始化顶点数量this.V = V;//初始化边的数量this.E = 0;//初始化邻接表this.adj = new Queue[V];//初始化邻接表中的空队列for (int i = 0; i < adj.length; i++) {adj[i] = new Queue<Edge>();}}//获取图中顶点的数量public int V() {return V;}//获取图中边的数量public int E() {return E;}//向加权无向图中添加一条边epublic void addEdge(Edge e) {//获取边中的一个顶点vint v = e.either();//获取边中的另一个顶点wint w = e.other(v);//因为是无向图,所以边e需要同时出现在两个顶点的邻接表中adj[v].enqueue(e);adj[w].enqueue(e);//边的数量+1E++;}//获取和顶点v关联的所有边public Queue<Edge> adj(int v) {return adj[v];}//获取加权无向图的所有边public Queue<Edge> edges() {//创建一个队列,存储所有的边Queue<Edge> allEdge = new Queue<>();//遍历顶点,拿到每个顶点的邻接表for (int v = 0; v < this.V; v++) {//遍历邻接表,拿到邻接表中的每条边for (Edge e : adj(v)) {/*因为无向图中,每条边对象Edge都会在两个顶点的邻接表中各出现一次,为了不重复获取,暂定一条规则:除了当前顶点v,再获取边e中的另外一个顶点w,如果v<w则添加,这样可以保证同一条边只会被统计一次*/if (e.other(v) < v) {allEdge.enqueue(e);}}}return allEdge;}}
2.加权有向图
边的实现:
package 图;public class DirectedEdge {private final int v;//起点private final int w;//终点private final double weight;//当前边的权重//通过顶点v和w,以及权重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 from() {return v;}//获取有向边的终点public int to() {return w;}}
加权有向图的实现:
package 图;import 线性表.Queue;public class EdgeWeightedDigraph {//顶点总数private final int V;//边的总数private int E;//邻接表private Queue<DirectedEdge>[] adj;//创建一个含有V个顶点的空加权有向图public EdgeWeightedDigraph(int V) {//初始化顶点数量this.V = V;//初始化边的数量this.E = 0;//初始化邻接表this.adj = new Queue[V];//初始化邻接表中的空队列for (int i = 0; i < adj.length; i++) {adj[i] = new Queue<DirectedEdge>();}}//获取图中顶点的数量public int V() {return V;}//获取图中边的数量public int E() {return E;}//向加权有向图中添加一条边epublic void addEdge(DirectedEdge e) {//获取有向边的起点int v = e.from();//因为是有向图,所以边e只需要出现在起点v的邻接表中adj[v].enqueue(e);//边的数量+1E++;}//获取由顶点v指出的所有的边public Queue<DirectedEdge> adj(int v) {return adj[v];}//获取加权有向图的所有边public Queue<DirectedEdge> edges() {//创建一个队列,存储所有的边Queue<DirectedEdge> allEdge = new Queue<>();//遍历顶点,拿到每个顶点的邻接表for (int v = 0; v < this.V; v++) {//遍历邻接表,拿到邻接表中的每条边存储到队列中for (DirectedEdge e : adj(v)) {allEdge.enqueue(e);}}return allEdge;}}
