哈希3:认识并查集

并查集: 并查集主要有两个作用。1:它可以查询两个元素A和B是不是同一个集合里面的。2:它可以把A和B两个元素所在的集合合并起来,注意是两个元素所在的集合,而不是两个元素。使用并查集的时候要一次性把数据全部输入,不支持动态的变化。
下面来说一下实现并查集的结构:
在这里插入图片描述
使用这样一种方式,假设每一个元素都是自己的代表节点,用代表节点表示集合。

合并时:那个集合的元素更少,就挂在元素多的那个集合下面
在这里插入图片描述

查找时:两个元素不断往上找,如果两个元素的代表节点一样,那么则是在同一个集合上。

并查集的优化:查询元素的时候,如果查到这个元素,则把这个元素之前的元素全部打平,即直接放到代表节点的下面。
在这里插入图片描述
代码:


import java.util.HashMap;
import java.util.List;

public class Code_04_UnionFind {

	public static class Node {
	}

	public static class UnionFindSet {
		public HashMap<Node, Node> fatherMap; // key:child  value: father
		public HashMap<Node, Integer> sizeMap;// 这个代表节点集合一共有多少个节点

		public UnionFindSet() {
			makeSets(nodes);
		}

		private void makeSets(List<Node> nodes) {  //初始化并查集 一开始要把所有的数据都传进来
			fatherMap = new HashMap<Node, Node>();
			sizeMap = new HashMap<Node, Integer>();
			for (Node node : nodes) {
				fatherMap.put(node, node); //每一个节点都是一个集合,都是代表节点
				sizeMap.put(node, 1); //长度都是1
			}
		}
 
		private Node findHead(Node node) { //找到代表节点,并完成那个优化的功能
			Node father = fatherMap.get(node);
			if (father != node) {
				father = findHead(father);
			}
			fatherMap.put(node, father);
			return father; //把最上面的那个代表节点返回
		}
		
		public boolean isSameSet(Node a, Node b) {
			return findHead(a) == findHead(b); //看两个代表节点是不是一样
		}

		public void union(Node a, Node b) {
			if (a == null || b == null) {
				return;
			}
			Node aHead = findHead(a);
			Node bHead = findHead(b);
			if (aHead != bHead) {
				int aSetSize= sizeMap.get(aHead); //分别得到a和b集合的长度
				int bSetSize = sizeMap.get(bHead);
				if (aSetSize <= bSetSize) { //如果a的长度小于b,那么把a放在b集合的下面.反之,放在a的下面
					fatherMap.put(aHead, bHead);
					sizeMap.put(bHead, aSetSize + bSetSize);
				} else { 
					fatherMap.put(bHead, aHead);
					sizeMap.put(aHead, aSetSize + bSetSize);
				}
			}
		}

	}

	public static void main(String[] args) {

	}

}

当查询次数和合并次数的复杂度逼近O(n)的时候,可以认为单次的查询的复杂度是O(1)的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值