17、加权无向图
加权无向图是一种为每条边关联一个权重值或是成本的图模型。
这种图能够自然地表示许多应用。
在一副航空图中,边表示航线,权值则可以表示距离或是费用。
在一副电路图中,边表示导线,权值则可能表示导线的长度即成本,或是信号通过这条线所需的时间。
此时很容易就能想到,最小成本的问题,例如,从西安飞纽约,怎样飞才能使时间成本最低或者是金钱成本最低?
在下图中,从顶点0到顶点4有三条路径,分别为0-2-3-4,0-2-4,0-5-3-4,通过哪条路径到达4顶点最好呢?
此时就要考虑,那条路径的成本最低
17.1、边的表示
加权无向图中的边不能简单的使用v-w两个顶点表示了,而必须要给边 关联一个权重值,因此可以使用 对象 来描述一条边
17.2、加权无向图的实现
- API
- 代码
package chapter17;
import chapter03.Queue;
/**
* @author 土味儿
* Date 2021/9/16
* @version 1.0
* 加权无向图
*/
public class EdgeWeightedGraph {
/**
* 顶点数量
*/
private final int vNum;
/**
* 边数量
*/
private int eNum;
/**
* 邻接表
*/
private Queue<Edge>[] adj;
/**
* 构造器
* @param vNum
*/
public EdgeWeightedGraph(int vNum) {
// 初始化顶点数量
this.vNum = vNum;
// 初始化边数量
this.eNum = 0;
// 初始化邻接表
this.adj = new Queue[vNum];
// 初始化邻接表中的空队列
for (int i = 0; i < vNum; i++) {
this.adj[i] = new Queue<Edge>();
}
}
/**
* 得到顶点数量
* @return
*/
public int getVNum(){
return vNum;
}
/**
* 得到边数量
* @return
*/
public int geteNum(){
return eNum;
}
/**
* 添加一条边v-w
* @param e
*/
public void addEdge(Edge e){
// 因为是无向图,让边e同时出现在e的两个顶点的邻接表中
int v = e.either();
int w = e.other(v);
this.adj[v].enQueue(e);
this.adj[w].enQueue(e);
// 边数量加1
eNum++;
}
/**
* 获取顶点v的所有相邻顶点
* @param v
* @return
*/
public Queue<Edge> adj(int v){
return this.adj[v];
}
/**
* 获取加权无向图中的所有边
* @return
*/
public Queue<Edge> edges(){
// 创建一个队列对象,存储所有的边
Queue<Edge> allEdges = new Queue<>();
// 遍历图中的每一个顶点,找到每个顶点的邻接表,邻接表中存储了该顶点关联的每一条边
for(int v=0;v<vNum;v++){
// 遍历顶点v的邻接表,找到每一条和v关联的边
for (Edge e : adj(v)) {
// 每条边的两个顶点,一大一小,判断大小再添加,可以避免重复
if(e.other(v) < v){
allEdges.enQueue(e);
}
}
}
return allEdges;