抽象类
import java.util.List;
public abstract class Adjacency<V> {
/** 总权重 */
protected int totalWeight;
/** 顶点的父亲 */
protected int[] parent;
/** 保存顶点的添加顺序 */
protected List<Integer> list;
/**
* prim
* @param startingVertex 开始的顶点
*/
public abstract void prim(int startingVertex);
/**
* 打印结果
*/
public abstract void print();
}
邻接表
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AdjacencyList<V> extends Adjacency<V> {
public class Edge {
/** 起始顶点 */
public int start;
/** 结束顶点 */
public int end;
/** 权重 */
public int weight;
public Edge(int start, int end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
}
/** 存储顶点 */
public List<V> vertices = new ArrayList<>();
/** 邻接表 */
public List<List<Edge>> neighbors = new ArrayList<>();
public AdjacencyList(V[] vertices, int[][] edges) {
createWeightedGraph(Arrays.asList(vertices), edges);
}
/**
* 构建邻接线性表
*/
private void createWeightedGraph(List<V> vertices, int[][] edges) {
this.vertices = vertices;
for(int i = 0; i < vertices.size(); i++) {
neighbors.add(new ArrayList<>());
}
for(int i = 0; i < edges.length; i++) {
neighbors.get(edges[i][0])
.add(new Edge(edges[i][0], edges[i][1], edges[i][2]));
}
}
@Override
public void prim(int startingVertex) {
//权重
double[] cost = new double[vertices.size()];
for(int i = 0; i < cost.length; i++) {
//初始化
cost[i] = Double.POSITIVE_INFINITY;
}
//初始化是0
cost[startingVertex] = 0;
//父节点
this.parent = new int[vertices.size()];
parent[startingVertex] = -1;
//树的总权值
this.totalWeight = 0;
//保存符合条件的顶点。
this.list = new ArrayList<>();
//找出最小权重
while(list.size() < vertices.size()) {
//当前顶点
int u = -1;
double currentMinCost = Double.POSITIVE_INFINITY;
for(int i = 0; i < vertices.size(); i++) {
if(!list.contains(i) && cost[i] < currentMinCost) {
currentMinCost = cost[i];
u = i;
}
}
//增添新的顶点
list.add(u);
//把当前权值增加给数的总权值
totalWeight += cost[u];
//在待查找的顶点调整顶点相邻边的cost数组
for(Edge e : neighbors.get(u)) {
if(!list.contains(e.end) && cost[e.end] > e.weight) {
cost[e.end] = e.weight;
parent[e.end] = u;
}
}
}
}
@Override
public void print() {
System.out.println("total weight is: " + super.totalWeight);
System.out.print("查找顺序为:");
for(int i : super.list) {
System.out.print(" " + vertices.get(i));
}
System.out.println("\n节点之间的关系为: ");
int[] parent = super.parent;
for(int i = 0; i < parent.length; i++) {
if(parent[i] != -1) {
System.out.println(vertices.get(i) + "---" + vertices.get(parent[i]));
}
}
}
}
邻接矩阵
import java.util.ArrayList;
public class AdjacencyMatrix<V> extends Adjacency<V> {
private String[] vertices;
private int[][] matrix;
public AdjacencyMatrix(String[] vertices, int[][] matrix) {
this.vertices = vertices;
this.matrix = matrix;
}
@Override
public void prim(int startingVertex) {
//权重
double[] cost = new double[vertices.length];
for(int i = 0; i < cost.length; i++) {
//初始化
cost[i] = Double.POSITIVE_INFINITY;
}
//初始化是0
cost[startingVertex] = 0;
//父节点
this.parent = new int[vertices.length];
parent[startingVertex] = -1;
//树的总权值
this.totalWeight = 0;
//保存符合条件的顶点。
this.list = new ArrayList<>();
//找出最小权重
while(list.size() < vertices.length) {
//当前顶点
int u = -1;
double currentMinCost = Double.POSITIVE_INFINITY;
for(int i = 0; i < vertices.length; i++) {
if(!list.contains(i) && cost[i] < currentMinCost) {
currentMinCost = cost[i];
u = i;
}
}
//增添新的顶点
list.add(u);
//把当前权值增加给数的总权值
totalWeight += cost[u];
//在待查找的顶点调整顶点相邻边的cost数组
for(int e = 0; e < matrix[u].length; e++) {
if(!list.contains(e) && cost[e] > matrix[u][e]) {
cost[e] = matrix[u][e];
parent[e] = u;
}
}
}
}
@Override
public void print() {
System.out.println("total weight is: " + super.totalWeight);
System.out.print("查找顺序为:");
for(int i : super.list) {
System.out.print(" " + vertices[i]);
}
System.out.println("\n节点之间的关系为: ");
int[] parent = super.parent;
for(int i = 0; i < parent.length; i++) {
if(parent[i] != -1) {
System.out.println(vertices[i] + "---" + vertices[parent[i]]);
}
}
}
}
测试代码
public class TestPrim {
public static void main(String[] args) {
//测试用例随意写的
String[] vertices = {"北京", "上海", "广州", "杭州", "长沙", "武汉", "南京"};
System.out.println("----------邻接表----------");
int[][] edges = {
{0, 1, 7807}, {0, 3, 1331}, {0, 5, 2097},
{1, 0, 7807}, {1, 2, 381}, {1, 3, 1267},
{2, 1, 381}, {2, 3, 1015}, {2, 4, 1663},
{3, 0, 1331}, {3, 1, 1267}, {3, 2, 1015}, {3, 4, 599}, {3, 5, 1003},
{4, 2, 1663}, {4, 3, 599}, {4, 5, 533},
{5, 0, 2097}, {5, 3, 1003}, {5, 4, 533}, {5, 6, 983},
{6, 5, 983}
};
Adjacency<String> adjacencyList = new AdjacencyList<>(vertices, edges);
adjacencyList.prim(0);
adjacencyList.print();
System.out.println("----------邻接矩阵----------");
int[][] matrix = {
{0, 7807, 0, 1331, 0, 2097, 0}, //北京
{7870, 0, 381, 1267, 0, 0, 0}, //上海
{0, 381, 0, 1015, 1663, 0, 0}, //广州
{1331, 1267, 1015, 0, 599, 1003, 0}, //杭州
{0, 0, 1663, 599, 0, 533, 0}, //长沙
{2097, 0, 0, 1003, 533, 0, 983}, //武汉
{0, 0, 0, 0, 0, 983, 0} //南京
};
Adjacency<String> adjacencyMatrix = new AdjacencyMatrix<>(vertices, matrix);
adjacencyMatrix.prim(0);
adjacencyList.print();
}
}
输出结果
----------邻接表----------
total weight is: 4842
查找顺序为: 北京 杭州 长沙 武汉 南京 广州 上海
节点之间的关系为:
上海---广州
广州---杭州
杭州---北京
长沙---杭州
武汉---长沙
南京---武汉
----------邻接矩阵----------
total weight is: 4842
查找顺序为: 北京 杭州 长沙 武汉 南京 广州 上海
节点之间的关系为:
上海---广州
广州---杭州
杭州---北京
长沙---杭州
武汉---长沙
南京---武汉