java实现prim(普里姆)最小生成树

java实现prim(普里姆)最小生成树
思路是这样: (思路大可不看,网上都是)
1、首先一个网,比如0-9为10个顶点嘛,(脑海中)让他里面的顶点都在集合V中,然后先找一个源点0
2、然后把这个源点0放在你的脑海中的集合S中,然后剩下的1-9顶点都放在脑海中的V-S里面。
3、然后就遍历S里面所有点与V-S中的邻接顶点的权值,找出权值最小的那个,把对应的V-S里面的那个顶点拉到S中。
比如:现在S中有0,他和顶点1,2,3互为邻接顶点,权值分别是5,6,7;那么就把顶点1放到S中。然后此时S中就有0和1两个顶点了。
还是比如:现在S中有0和1了,然后现在0和V-S中的2、3还是邻接顶点,权值为6、7。假如1和V-S中的邻接顶点是3、5,权值分别是1、4;那么这些权值里面最小的就是1,即顶点1和3之间的权值,就把3放到S中。。。。。
4、重复上面的步骤。最后把所有的顶点都放在S中,这个S就是个最小生成树了。

原理大家肯定都懂,上面的可看可不看,直接来看代码吧还是
当然这个代码里面我打印了每一步的步骤方便大家和我自己理解,大家复制即可运行,观察打印结果应该就差不多懂了。

import java.util.Arrays;
public class Prim {
	public static void main(String[] args) {
		int v=10;  //这个是有几个顶点
		int [][]g=new int[v][v]; //这个是建一个二维数组,就是邻接矩阵嘛,这里是无向图
		for (int i = 0; i < v; i++) { //给所有的都赋值9999
            for (int j = 0; j < v; j++) {
                g[i][j] = 9999; 
            }
        }
  //然后给相连的点赋权值,这样如果两点之间权值是9999,就代表两点不相连
		g[0][1]=1;
		g[0][2]=3;
		g[0][3]=3;
		g[0][4]=5;
		g[0][5]=4;
		g[0][6]=6;
		g[0][7]=9;
		g[0][8]=8;
		g[0][9]=7;
		g[1][2]=7;
		g[1][3]=5;
		g[3][5]=11;
		g[5][7]=13;
		g[5][9]=7;
		g[7][9]=5;
		g[9][8]=9;
		g[8][6]=11;
		g[6][4]=10;
		g[6][2]=14;
		g[4][2]=5;
		//无向图嘛,你连我我连你,然后就颠倒过来嘛。比如0和1的权值是1,那么1和0的也是1.
		for (int i = 0; i < v; i++) {
            for (int j = 0; j < v; j++) {
                g[j][i] = g[i][j];
            }
        }
   //这个是建立一个数组,存放生成最小树的顺序
		int a[]=new int[v];
		a=prim(g, 0);//调用方法,用a接着
		System.out.println(Arrays.toString(a));//打印a
	}
//实现代码如下
	public static int[] prim(int g[][],int source) {
		int[] visited=new int[g.length]; //首先定义一个数组记录是否被参观过,或者说是否在集合S中,亦或者说是否在最小生成树中
		visited[0]=1;//0号是起始节点嘛,等于1说明他在最小树里面了已经,让它为1
		int mst[]=new int[g.length];//建立一个装最小生成树结点的数组
		for(int i=0;i<mst.length;i++) {
			mst[i]=10000;//让里面的所有值都为1w,当然这个随你,1y也可
		}
		mst[0]=0;//0号已经在最小生成树里面,就让对应的位置为顶点的值0
		for(int m=1;m<g.length;m++) {
			int i=0;
			int min=Integer.MAX_VALUE;
			int index=0;	
			System.out.println("此时最小树有"+Arrays.toString(mst));
			while(mst[i]!=10000) {//循环遍历一整个树找到和V-S中结点权值最小的那个。
				for(int j=0;j<g.length;j++) {
					System.out.println("现在遍历的是"+mst[i]+"和"+j+"结点");
					if(visited[j]==0&&g[mst[i]][j]<min&&g[mst[i]][j]!=9999) {//如果这个顶点没有在最小树里面,然后权值更小就保存
						System.out.println("此结点符合要求,最短路径由"+min+"更改为"+g[mst[i]][j]);
						min=g[mst[i]][j];
						index=j;
					}else {
						System.out.println("不合适或者不连通");
					}
				}
				//上面for循环结束之后,会得到一个最小的min权值以及对应的顶点是谁。然后循环完集合最小生成树中的所有的权值,找到最小的
				i++;
			}

				System.out.println("旧的最小生成树遍历完成,将V-S中离S最近的一个结点"+index+"放入新最小生成树中");
				mst[i]=index;	
				visited[index]=1;
		
		}
		return mst;
	}
	
}

这个代码我自己写的,谁也没参考,对不对我不知道哈

这个图我是这样画的,对不对不保证哈
在这里插入图片描述
运行的结果是这样的,每一次干的啥都打印出来了在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值