最小生成树克鲁斯卡尔算法

本文介绍了克鲁斯卡尔算法,一种用于寻找连通网最小生成树的算法,特别适合边稀疏的网络。算法通过选择权值最小的边并检查是否形成环来构建最小生成树。代码示例展示了如何在Java中实现该算法,通过遍历所有边并更新节点的父节点来避免环的形成。
摘要由CSDN通过智能技术生成


一、什么是克鲁斯卡尔?

克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树.

二、原理

克鲁斯卡尔算法的思想是站在了上帝视角.先把权值最短的边一个个挑出来,然后判断挑出来的边是否构成环,如果不构成环则是最小生成树的一部分,否则边过滤

三、代码实现

/**
 * 最小生成树
 * 克鲁斯卡尔算法
 */
public class Test {


	/**
	 * 所有边集合
	 */
	private static final List<Edges> EDGES_LIST;
	private static final List<Integer> PARENT;

	static {

		Edges edges0 = new Edges(4, 7, 7);
		Edges edges1 = new Edges(2, 8, 8);
		Edges edges2 = new Edges(0, 1, 10);
		Edges edges3 = new Edges(0, 5, 11);
		Edges edges4 = new Edges(1, 8, 12);
		Edges edges5 = new Edges(3, 7, 16);
		Edges edges6 = new Edges(1, 6, 16);
		Edges edges7 = new Edges(5, 6, 17);
		Edges edges8 = new Edges(1, 2, 18);
		Edges edges9 = new Edges(6, 7, 19);
		Edges edges10 = new Edges(3, 4, 20);
		Edges edges11 = new Edges(3, 8, 21);
		Edges edges12 = new Edges(2, 3, 22);
		Edges edges13 = new Edges(3, 6, 24);
		Edges edges14 = new Edges(4, 5, 26);
		EDGES_LIST = Arrays.asList(edges0, edges1, edges2, edges3, edges4, edges5, edges6, edges7, edges8, edges9, edges10, edges11, edges12, edges13, edges14);
		PARENT = new ArrayList<>(EDGES_LIST.size());
		for (int i = 0; i < EDGES_LIST.size(); i++) {
			PARENT.add(0);
		}


	}


	public static void main(String[] args) {

		for (Edges edges : EDGES_LIST) {
			int begin = find(edges.getBegin());
			int end = find(edges.getEnd());
			// 如果begin == end 说明已经成环 ,成环的edges边不能要
			if (begin != end) {
				System.out.println("路径:" + edges.getBegin() + "-" + edges.getEnd() + " 权值:" + edges.getWeight());
				PARENT.set(end, begin);
			}
		}
	}


	/**
	 * 查找当前节点的起始节点
	 *
	 * @param index
	 * @return
	 */
	private static int find(int index) {
		while (PARENT.get(index) > 0) {
			index = PARENT.get(index);
		}
		return index;

	}

}


class Edges implements Comparable<Edges> {

	/**
	 * 起始点
	 */
	private int begin;
	/**
	 * 终点
	 */
	private int end;
	/**
	 * 权值
	 */
	private int weight;

	public int getBegin() {
		return begin;
	}

	public void setBegin(int begin) {
		this.begin = begin;
	}

	public int getEnd() {
		return end;
	}

	public void setEnd(int end) {
		this.end = end;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

	public Edges(int begin, int end, int weight) {
		this.begin = begin;
		this.end = end;
		this.weight = weight;
	}

	@Override
	public int compareTo(Edges o1) {

		return this.weight > o1.weight ? 1 : -1;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值