并查集

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。

 

并查集实现起来,就是把一个集合的元素用一个标号来表示,每个节点的最终祖先节点就标记为这个标号,而如果用数组保存的话,这个标号就是数组元素的index值。

 

下面举个例子就明白了,现在的问题是:假如有输入集合 (10 7) (2 4) (5 7) (1 3) (8 9) (1 2) (5 6) (2 3),如果2个集合有交集,则认为这2个集合属于一个更大的集合,如(10 7) (5 7)属于(10 7 5),按照这样的规则,判断(3) (4)是否在一个集合内。

 

假设初始每个元素都是单独的树,那么显然每个元素都是树根,一共有10个树

 

给定(10 7) 说明10 7 在一个集合,我们约定前面的元素作为父节点,那森林变成

 

上面的集合全部遍历之后,森林变为

 

可见这个时候就容易判断(3)和(4)是否在一个集合。

 

算法用JAVA实现,除了初始化外包括2个对外操作,寻找父亲节点和合并集合。

寻找父亲:就是找到根节点,它的特点是指向自己。

合并集合:如果给定输入集合2个元素属于不同的根节点,那就合并根节点,也就是把一个元素的根节点指向另一个元素根节点。

 

定义并查集的类:

 

 

测试主程序:

 

 

这里需要注意的是有2个优化,因为有可能出现很不平衡的树,如下面

需要调整为这样的树

 

所以在合并集合的时候,应该让子节点少的指向子节点多的,这就是引入number数组的原因,统计子节点个数。

 

并查集的一个应用:

给定一个字符串的集合,格式如:{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh},要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出{aaa bbb ccc ddd hhh},{eee fff}, {ggg}。

 

将元素进行编码,输入集合相当于(1 2),(2 3),(2 4),(5 6),(7),(4 8),

查找并且合并集合后数组为:2(1), 2(5), 2(1), 2(1), 6(1), 6(1), 7(1), 2(1)

输出只要输出森林中的各个树。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值