Java-并查集

假设最开始有这样一个坨元素 a b c d e f g h

最开始这些元素各自为一个集合{a} {b} {c} {d} {e} {f} {g}

并查集的作用是把这些元素链接起来

假如要把b和a链接起来 就变成了{a,b}{c} {d} {e} {f} {g}

再把c和b链接起来呢(与a和c连接起来等效哦)?  {a,b,c}{d} {e} {f} {g}

点定义 

class Node{
    int value;
}

并查集定义

并查集中的成员变量

class Unionfind{
	HashMap<Integer,Node> map = new HashMap<Integer, Node>();
	HashMap<Node, Node> parents = new HashMap<Node, Node>();
	HashMap<Node, Integer> size = new HashMap<Node, Integer>();
}

并查集中的成员方法

1.取得父节点

public Node getfather(Node node) {
		Stack<Node> stack = new Stack<Node>();
		while(parents.get(node)!=node) {
			stack.push(node);
			node = parents.get(node);
		}
		while(!stack.isEmpty()) {
			parents.put(stack.pop(), node);
		}
		return node;
	}

如果只是单纯的取得父节点只需要

public Node getfather(Node node) {
		while(parents.get(node)!=node) {
			node = parents.get(node);
		}
		return node;
	}

我们再此基础上做了一个优化,把这条路径上的每一个节点都直接连接到父节点上,下次查找的时候就不需要再遍历了

2.判断两个点是否在同一个集中

public boolean issame(Node node1,Node node2) {
		if (!map.containsKey(node1) || !map.containsKey(node2)) {
			return false;
		}
		return parents.get(node1)==parents.get(node2);
	}

3.连接两个点

两个点连接 那么就相当于两个点所在的集连接了

我们选择把小的集接在大的集上面

记得把小的集的size消除掉

看一个集的大小 就是这个集的头元素对应的size

如果他们是同一个头的话 那么就会把这个头的size  remove掉 所以要加一个if

public void union(Node node1,Node node2) {
		if (!map.containsKey(node1) || !map.containsKey(node2)) {
			return;
		}
		Node head1 = getfather(node1);
		Node head2 = getfather(node2);
		if (head1 != head2) {
		Node big = size.get(head1)>size.get(head2)?node1:node2;
		Node small = big==head1?head2:head1;
		parents.put(small,big);
		size.put(big, size.get(head1)+size.get(head2));
		size.remove(small);
		}
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值