kruskal

最小生成树算法-kruskal:

graph[][] 图

lines[] 图的所有边

nodes[] 所有节点(初始值所有节点,每个节点的父子均为空)

static class Line{
		public Line(int from, int to, int weight){
			this.from = from;
			this.to = to;
			this.weight = weight;
		}
		int from;
		int to;
		int weight;
		public int getFrom() {
			return from;
		}
		public void setFrom(int from) {
			this.from = from;
		}
		public int getTo() {
			return to;
		}
		public void setTo(int to) {
			this.to = to;
		}
		public int getWeight() {
			return weight;
		}
		public void setWeight(int weight) {
			this.weight = weight;
		}
	}


1:对 lines 排序 遍历 lines

public static List<Line> getSortLines(int[][] graph){
		List<Line> lines = new ArrayList<Kruskal.Line>();
		for (int i = 0; i < graph.length; i++){
			for (int j = 1; j < graph[i].length; j++){
				lines.add(new Line(i, j, graph[i][j]));
			}
		}
		LOG.d("before sort:", lines);
		lines = sortList(lines);
		LOG.d("after sort:", lines);
		return lines;
	}
	
	public static List<Line> sortList(List<Line> lines){
		Collections.sort(lines, new Comparator<Line>() {
			@Override
			public int compare(Line o1, Line o2) {
				return o1.weight - o2.weight;
			}
		});
		return lines;
	}


2:从 lines 获取边 min。

3:判断边的起点 from,终点 to 是否在一个树上。

如果在一个树上回到 1,如果不在:from.next.add(to) 在nodes 中删除 to;(或者此处用 prev 数组表示父子节点关系,此处就要将 prev[to]  = from )

注:此处可添加 sum+= min;用于计算最小生成树的路长总和。

4:直到所有节点在一个树中。

	// lines所有边集合
	// previous前驱节点集合
	public static int kruskal(int[][] graph){
		List<Line> lines = getSortLines(graph);
		int[] previous = new int[graph.length];
		for (int i = 0; i < graph.length; i++){
			previous[i] = i;
		}
		int sum = 0;
		for (int i = 0; i < lines.size(); i++){
			int k = 0; 
			int j = 0;
			for (k = lines.get(i).from; previous[k] != k;k = previous[k]){
			}
			for (j = lines.get(i).to; previous[j] != j; j = previous[j]){
			}
			LOG.d(k, " ", j);
			if (k != j && lines.get(i).weight != GraphUtils.MAX){
				LOG.d(lines.get(i));
				previous[j] = previous[lines.get(i).from];
				sum += lines.get(i).weight;
			}
		}
		return sum;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值