Prim算法 数组实现

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		 带权路径图1
		int net1[][] = {	{ 0, 1, 2, 3, 4, 5 },
						{ 1, 0, 3, 2, 0, 0 },
						{ 2, 3, 0, 0, 0, 6 },
						{ 3, 2, 0, 0, 7, 0 },
						{ 4, 0, 0, 7, 0, 5 }, 
						{ 5, 0, 6, 0, 5, 0 } };
		// 带权路径图2
		// 带权路径图2
		int net[][] = {	{ 0, 6, 0, 0, 7, 4 },
						{ 6, 0, 3, 4, 0, 0 },
						{ 0, 3, 0, 0, 0, 2 },
						{ 0, 4, 0, 0, 5, 0 },
						{ 7, 0, 0, 5, 0, 1 }, 
						{ 4, 0, 2, 0, 1, 0 } };
		net = prim(net1);
		for (int i = 0; i < net.length; i++) {
			for (int j = 0; j < net.length; j++) {
				System.out.print(net[i][j]+" ");
			}
			System.out.println();
		}
	}

	public static int[][] prim(int net[][]) {

		int result[][] = new int[net.length][net.length];
		int x = 0, y = 1;
		int set[] = new int[net.length];
		// 初始化结果数组
		for (int i = 0; i < net.length; i++) {
			for (int j = 0; j < net.length; j++) {
				result[i][j] = 0;
			}
		}
		// 将最小权值的两点放入集合
		for (int i = 0; i < net.length; i++) {
			for (int j = i + 1; j < net.length; j++) {
				if (net[i][j] <= net[x][y] && net[i][j] != 0) {
					x = i;
					y = j;
				}
			}
		}
		InsertSort(set, x);
		InsertSort(set, y);
		// 更新结果数组的权值(无向)
		result[x][y] = net[x][y];
		result[y][x] = net[y][x];
		// 循环 直到set集合中点的数目达到6
		while(getSetNumber(set) < 6){
//			System.out.println(1);
		// 遍历集合中的边 获得最小权值的边 放入集合 设置result的权值
			int pow = 9999;
			//从第一个元素开始遍历 set[k]为一个顶点的下标+1
			for (int k = 0; k < getSetNumber(set); k++) {
				//遍历元素的边 i要还原下标 所以-1 因为在set数组中是用下标+1的方式储存 
				for (int i = set[k]-1; i < set.length; i++) {
					for (int j = 0; j < set.length; j++) {
						//只有不与已在集合内的元素的边(+1) 和 权值更小的边 但不为零 可以作为目标
						if( !isCover(set,j+1) && net[i][j] <= pow && net[i][j] != 0){
							pow = net[i][j];
//							System.out.println(pow+" "+i+" "+j);
							x = i;
							y = j;
						}
					}
				}
			}
			//跟新集合内的元素和结果的权值
			InsertSort(set, x);
			InsertSort(set, y);
			result[x][y] = net[x][y];
			result[y][x] = net[y][x];

//			for (int i = 0; i < set.length; i++) {
//				System.out.print(set[i]+" ");
//			}
//			System.out.println();
		}

		return result;
	}
	//返回数组里非0的数字的个数
	public static int getSetNumber(int[] set){
		for (int i = 0; i < set.length; i++) {
			if(set[i] == 0)
				return i;
			if(i + 1 == set.length)
				return set.length;
		}
		return 0;
	}
	//判断数字n 是否在set里
	public static boolean isCover(int[] set, int n) {
		for (int i = 0; i < set.length; i++) {
			if (set[i] == n)
				return true;
		}
		return false;
	}
	//动态增序插入一个数 如果这个数已经存在在数组中 就不插入
	public static void InsertSort(int[] set, int num) {
		num += 1;
		// 数组中没有数 直接放到第一位
		if (set[0] == 0)
			set[0] = num;
		else {
			// 如果已经有相等的数 不进行插入
			for (int i = 0; i < set.length; i++) {
				if (num == set[i])
					return;
			}
			for (int i = 0; i < set.length; i++) {
				// 如果插入的数小于第i个数 往后偏移一位 放在第i位
				if (num < set[i]) {
					for (int j = set.length - 1; j > i; j--) {
						set[j] = set[j - 1];
					}
					set[i] = num;
					return;
				}
			}
			// 如果插入的数大于所有数 放在最后
			for (int i = 0; i < set.length; i++) {
				if (set[i] == 0) {
					set[i] = num;
					return;
				}
			}
		}

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值