1、建立结点类
//结点
public class Node {
private String data;
private boolean isVisited;
public Node(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public boolean isVisited() {
return isVisited;
}
public void setVisited(boolean isVisited) {
this.isVisited = isVisited;
}
}
2、用来存储顶点之间有无边、及权值大小的边类
//边
public class Edge {
private int start;
private int end;
private int weight;
private boolean isSelected; // 是否已被选中
public Edge(int start, int end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
}
3、数据源
//数据源
public class GraphData {
// 邻接矩阵
public int[][] getMatrix() {
// 非0代表权值,0代表无边
int[][] matrix = { { 0, 6, 0, 0, 5, 1 }, { 6, 0, 3, 0, 0, 2 }, { 0, 3, 0, 7, 0, 8 }, { 0, 0, 7, 0, 2, 4 },
{ 5, 0, 0, 2, 0, 9 }, { 1, 2, 8, 4, 9, 0 } };
return matrix;
}
// 顶点标签
public String[] getNodeData() {
String[] nodeData = { "A", "B", "C", "D", "E", "F" };
return nodeData;
}
}
4、Prim算法
//最小生成树之Prim算法实现
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class Prim {
// 顶点列表
private List<Node> list = new ArrayList<Node>();
GraphData gd = new GraphData();
public Prim() {
// 顶点数据
String[] nodeData = gd.getNodeData();
for (String data : nodeData) {
list.add(new Node(data));
}
getMinTree(0);
}
private void getMinTree(int nodeIndex) {
// 邻接矩阵
int[][] matrix = gd.getMatrix();
// 顶点个数
int n = matrix.length;
// 存储已确定的边的数组
Edge[] treeEdges = new Edge[n - 1];
// 存放已确定的点的索引的集合
Vector<Integer> nodeVec = new Vector<Integer>();
// 把已确定的点所连接的所有边放进一个集合,即备选边的集合
Vector<Edge> edgeVec = new Vector<Edge>();
// 当“取得的边数==顶点数-1”时,可停止算法
// 计算边的数量
int edgeCount = 0;
// 总路径长度
int sum = 0;
// 将第一个点放进点的集合中
nodeVec.add(nodeIndex);
// 设置该点也被访问
list.get(nodeIndex).setVisited(true);
// 打印传进来的点
System.out.println("第" + nodeVec.size() + "个确定的点:" + list.get(nodeIndex).getData());
// 1、找到算法的结束条件
while (edgeCount < n - 1) {
// 取出传进来的顶点的索引
int temp = nodeVec.get(nodeIndex);
/**
* 寻找与该顶点连接的所有边 for循环一结束,表示已将该顶点连接的所有边放入到备选表集合中了
*/
for (int i = 0; i < n; i++) {
// 有边
if (matrix[temp][i] != 0) {
// 顶点已被访问过
if (list.get(i).isVisited()) {
continue;
} else {
// 顶点还没被访问过,那么这条边应放入备选边的集合中
edgeVec.add(new Edge(temp, i, matrix[temp][i]));
}
}
}
/**
* 从备选边集合中找到最小的边 把最小边连着的未确定的顶点放入到已确定的点的集合中
*/
// 取得最小边的在备选边集合中索引
int minEdge = getMinEdge(edgeVec);
// 设置边为已被访问状态
edgeVec.get(minEdge).setSelected(true);
// 将边放入到已确定的边的数组中
treeEdges[edgeCount] = edgeVec.get(minEdge);
// 路径长度
sum += edgeVec.get(minEdge).getWeight();
// 边数加1
edgeCount++;
// 找到与当前最小边所连接的那个点,edgeVec.get(minEdge).getStart()是当前这个点
int curNodeIndex = edgeVec.get(minEdge).getStart();
int nextNodeIndex = edgeVec.get(minEdge).getEnd();
// 将点放入到已确定的点的集合中
nodeVec.add(nextNodeIndex);
// 设置该点为已被访问状态
list.get(nextNodeIndex).setVisited(true);
// 打印顶点和边的信息
System.out.println("第" + edgeCount + "条确定的边:" + list.get(curNodeIndex).getData() + "-->"
+ list.get(nextNodeIndex).getData() + ":" + matrix[curNodeIndex][nextNodeIndex]);
// 打印下一次要循环的点
System.out.println("第" + nodeVec.size() + "个确定的点:" + list.get(nextNodeIndex).getData());
nodeIndex++;
}
System.out.println("路径长度为:" + sum);
}
private int getMinEdge(Vector<Edge> edgeVec) {
int max = Integer.MAX_VALUE;
// 最小权值
int minWeight = max;
// 最小边的索引
int edgeIndex = 0;
// 找出第一条没有被访问过的边
for (int i = 0; i < edgeVec.size(); i++) {
// 边未被访问过
if (!edgeVec.get(i).isSelected() && edgeVec.get(i).getWeight() < minWeight) {
// 将边的权值赋给minWeight
minWeight = edgeVec.get(i).getWeight();
// 最小边的索引为i
edgeIndex = i;
} else if (edgeVec.get(i).isSelected()) {
continue;
}
}
// 所有的边都已被选中,找最小边失败
if (minWeight == max)
return -1;
return edgeIndex;
}
}
5、测试
public class Test {
public static void main(String[] args) {
new Prim();
}
}
6、测试结果