1.掌握图的定义及实现;
2.掌握使用Prim算法构造最小生成树。
目的:使用Prim算法构造最小生成树,并在控制台显示。
具体的项目结构:
程序设计思路:
-
定义边类型edge(权值weight,起点start,终点end)
-
在Prim类中自定义下列功能:
初始化无向网邻接矩阵init()
构造最小生成树方法prim()
显示最小生成树show() -
编写测试类Test调用功能方法
核心代码:
Edge.java:
package ds.mintree;
/**
* 无向网络中边类型
* @author 1
*
*/
public class Edge {
//起点fromVex
private int fromVex;
//终点endVex
private int endVex;
//权值weight
private int weight;
public Edge() {
super();
}
public Edge(int fromVex, int endVex, int weight) {
super();
this.fromVex = fromVex;
this.endVex = endVex;
this.weight = weight;
}
public int getFromVex() {
return fromVex;
}
public void setFromVex(int fromVex) {
this.fromVex = fromVex;
}
public int getEndVex() {
return endVex;
}
public void setEndVex(int endVex) {
this.endVex = endVex;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
Prim.java:
package ds.mintree;
import java.util.Scanner;
/**
* 使用prim算法构造最小生成树
*
* @author 1
*
*/
public class Prim {
// 无向网络的邻接矩阵dist
private int[][] dist;
// 最小生成树数组tree
private Edge[] tree;
// 无向网络的顶点数vexNum、边数edgeNum
private int vexNum, edgeNum;
// 构造方法
public Prim() {
super();
}
public Prim(int vexNum, int edgeNum) {
this.vexNum = vexNum;
this.edgeNum = edgeNum;
dist = new int[vexNum][vexNum];
tree = new Edge[vexNum - 1];
}
// 初始化邻接矩阵init
public void init() {
for (int i = 0; i < vexNum; i++) {
for (int j = 0; j < vexNum; j++)
dist[i][j] = 999;
}
// 从键盘输入边的信息,包括起点终点,存入邻接矩阵相应的位置
Scanner in = new Scanner(System.in);
int f, e, w;// 起点、终点、权值
for (int j = 1; j <= edgeNum; j++) {
System.out.print("请输入第" + j + "条边的信息(起点、终点、权值):");
f = in.nextInt();
e = in.nextInt();
w = in.nextInt();// 1 2 6,下标从0开始
dist[f - 1][e - 1] = w;
dist[e - 1][f - 1] = w;
}
}
// prim算法
public void prim() {
// 构造初始候选边集
for (int j = 1; j < vexNum; j++) {
tree[j - 1] = new Edge();
tree[j - 1].setFromVex(1);
tree[j - 1].setEndVex(j + 1);
tree[j - 1].setWeight(dist[0][j]);// 起点从1开始,下标位0
}
// 扩充最小生成树的第k条边(k:0~n-2)
int min, m = -1; // min最短边权值,m最短边下标
Edge e = new Edge();// 交换时的中间变量
for (int k = 0; k < vexNum - 1; k++) {
// 查找最短边
min=999;
for (int j = k; j < vexNum - 1; j++) {
if (tree[j].getWeight() < min) {
min = tree[j].getWeight();
m = j;
}
}
// 把最短边与查找范围内第一个位置交换
e = tree[m];
tree[m] = tree[k];
tree[k] = e; //(1,3,1)
int v = tree[k].getEndVex();//v表示最短边的终点
// 调整候选边集
for(int j=k+1;j<vexNum-1;j++){
int d = dist[v-1][tree[j].getEndVex()-1];//和原来的权值做比较
if(d<tree[j].getWeight()){
tree[j].setFromVex(v);
tree[j].setWeight(d);
}
}
}
}
// 输出最小生成树的信息show
public void show() {
System.out.println("起点\t\t终点\t\t权值");
for(int k=0;k<vexNum-1;k++){
System.out.println(tree[k].getFromVex()+"\t\t"+tree[k].getEndVex()+"\t\t"+tree[k].getWeight());
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
Prim prim = new Prim(6,10);//6个顶点10条边
prim.init();
prim.prim();
prim.show();
}
}
运行结果截图:
本文章仅供学习和参考,如果发现有问题的地方还请大家多多指正!