/*
* @topic:Prim最小生成树
*/
class Edge {// 边
public int srcVert;// 边的起始顶点
public int destVert;// 边的终止顶点
public int distance;// 边的长度
public Edge(int sv, int dv, int d) {
srcVert = sv;
destVert = dv;
distance = d;
}
}
class Vertex {// 顶点
public char label;
public boolean isInTree;
public Vertex(char lab) {
label = lab;
isInTree = false;
}
}
class PriorityQ {// 边的优先级队列,将边以权重由大到小进行排序
private final int SIZE = 20;
private Edge[] queArray;
private int size;
public PriorityQ() {
queArray = new Edge[SIZE];
size = 0;
}
public void insert(Edge item) {
int j;
for (j = 0; j < size; j++) {
if (item.distance >= queArray[j].distance)
break;
}
for (int k = size - 1; k >= j; k--) {
queArray[k + 1] = queArray[k];
}
queArray[j] = item;
size++;
}
public Edge removeMin() {
return queArray[--size];
}
public void removeN(int n) {
for (int j = n; j < size - 1; j++) {
queArray[j] = queArray[j + 1];
}
size--;
}
public int size() {
return size;
}
public Edge peekN(int n) {
return queArray[n];
}
public int find(int index) {
for (int j = 0; j < size; j++) {
if (queArray[j].destVert == index)
return j;
}
return -1;
}
}
class Graph {
private final int MAX_VERTS = 20;
private final int INFINITY = 10000;
private Vertex vertexList[];// 顶点序列
private int adjMat[][];// 邻接矩阵
private int nVerts;// 顶点个数
private int currentVert;
private PriorityQ thePQ;
private int nTree;// 树中顶点的个数
public Graph() {
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++) {
for (int k = 0; k < MAX_VERTS; k++) {
adjMat[j][k] = INFINITY;
}
}// 构建邻接矩阵
thePQ = new PriorityQ();
}
public void addVertex(char lab) {
vertexList[nVerts++] = new Vertex(lab);
}
public void addEdge(int start, int end, int weight) {
adjMat[start][end] = weight;
adjMat[end][start] = weight;
}
public void displayVertex(int v) {
System.out.println(vertexList[v].label);
}
public void mst() {// minimum spanning tree
currentVert = 0;
while (nTree < nVerts - 1) {
vertexList[currentVert].isInTree = true;
nTree++;
// 将与当前顶点相邻的边插入到优先级队列中
for (int j = 0; j < nVerts; j++) {
if (j == currentVert)// 是当前顶点
continue;
if (vertexList[j].isInTree)// 已经在生成树中
continue;
int distance = adjMat[currentVert][j];
if (distance == INFINITY)// 不相邻
continue;
putInPQ(j, distance);
}
if (thePQ.size() == 0) {
System.out.println("GRAPH NOT CONNECTED");
return;
}
// 从优先级队列中取出最短的一条边
Edge theEdge = thePQ.removeMin();
int sourceVert = theEdge.srcVert;
currentVert = theEdge.destVert;
System.out.print(vertexList[sourceVert].label);
System.out.print(vertexList[currentVert].label + " ");
}
}
public void putInPQ(int newVert, int newDist) {
int queueIndex = thePQ.find(newVert);
if (queueIndex != -1) {
Edge tempEdge = thePQ.peekN(queueIndex);
int oldDist = tempEdge.distance;
if (oldDist > newDist) {
thePQ.removeN(queueIndex);
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge);
}
} else {
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge);
}
}
}
public class Prim {
public static void main(String[] args) {
Graph graph = new Graph();
graph.addVertex('1');
graph.addVertex('2');
graph.addVertex('3');
graph.addVertex('4');
graph.addVertex('5');
graph.addVertex('6');
graph.addEdge(0, 1, 6);
graph.addEdge(0, 2, 1);
graph.addEdge(0, 3, 5);
graph.addEdge(1, 2, 5);
graph.addEdge(1, 4, 3);
graph.addEdge(2, 3, 5);
graph.addEdge(2, 4, 6);
graph.addEdge(2, 5, 4);
graph.addEdge(3, 5, 2);
graph.addEdge(4, 5, 6);
graph.mst();
}
}
Prim最小生成树
最新推荐文章于 2024-02-15 20:50:29 发布