package com.guigu.algorithm.prim;
import java.util.Arrays;
/**
*@author: guorui fu
*@versiion: 1.0
*/
public class PrimAlgorithm {
public static void main(String[] args) {
char[] data = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int verxs = data.length;
//邻接矩阵使用二维数组描述
int[][] weight = new int[][]{
{10000,5,7,10000,10000,10000,2},
{5,10000,10000,9,10000,10000,3},
{7,10000,10000,10000,8,10000,10000},
{10000,9,10000,10000,10000,4,10000},
{10000,10000,8,10000,10000,5,4},
{10000,10000,10000,4,5,10000,6},
{2,3,10000,10000,4,6,10000}
};
//创建graph对象
MGraph graph = new MGraph(verxs);
//创建minTree
MinTree minTree = new MinTree();
minTree.createGraph(graph,verxs,data,weight);
//显示图
minTree.showGraph(graph);
//prim算法
minTree.prim(graph,0);
}
}
//创建最小生成树
class MinTree{
//创建图的邻接矩阵
/**
*
* @param graph 图对象
* @param data 图对应的顶点个数
* @param weight 图的邻接矩阵
*/
public void createGraph(MGraph graph,int verxs,char data[],int[][] weight){
int i,j;
for (int k = 0; k < verxs; k++) {//顶点
graph.data[k] = data[k];
for (int l = 0; l < verxs; l++) {
graph.weight[k][l] = weight[k][l];
}
}
}
//显示图的方法
public void showGraph(MGraph graph){
for (int[] link : graph.weight) {
System.out.println(Arrays.toString(link));
}
}
//编写prim算法,得到最小生成树
/**
*
* @param graph 图
* @param v 从哪个顶点开始
*/
public void prim(MGraph graph,int v){
//标记顶点是否被访问过 开始默认0
int[] visited = new int[graph.verxs];
//两个顶点的下标
int h1 = -1;
int h2 = -1;
int minWeight = 10000;
visited[v] = 1;//表示已访问
//更新已访问节点,循环n-1次,找到n个节点的n-1条边的最小权值
//已访问过节点之间不在计算之间的权值,保证每个节点都可以连接到
for (int i = 1; i < graph.verxs; i++) {
//下面两个for循环可以找出整个图中权值最小的边,
// 第一层for寻找所有已访问节点 在第二层visited[j] == 1完成控制目的
// 第二层for每一次都是从已访问节点出发 找当前节点到邻接未访问节点的最小权值,并记录权值坐标
//两层循环后可以找到所有当前状态所有已访问节点中邻接边最小权值
for (int j = 0; j < graph.verxs; j++) {//j节点表示被访问过的节点
for (int k = 0; k < graph.verxs; k++) {//k节点表示还没有访问过的节点
if (visited[j] == 1 && visited[k] == 0 &&
graph.weight[j][k] < minWeight){
//替换minWeight 寻找已经访问过的节点和未访问的节点见的权值最小边
minWeight = graph.weight[j][k];
h1 = j;
h2 = k;
}
}
}
//找到一条边是最小的
System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值:" + minWeight);
//将当前这个节点标记已经访问过
visited[h2] = 1;
minWeight = 10000;//重新设置
}
}
}
class MGraph{
int verxs ;//图的节点个数
char[] data;//存放节点数据
int[][] weight;//存放边,邻接矩阵
public MGraph(int verxs) {
this.verxs = verxs;
data = new char[verxs];
weight = new int[verxs][verxs];
}
}
[算法] 普里姆算法 找最小生成树
最新推荐文章于 2024-06-12 10:00:23 发布