并查集(2)

再优化


1.更好的方法是什么,当然是树形结构了。

方法2:

每个集合用一棵“有根树”表示定义数组 set[1..n]

set[i] = i , 则i表示本集合,是集合对应树的根

set[i] = j, j<>i, 则 j 是 i 的父节点. 



1

2

3

4

5

6

7

8

9

10

1

2

3

2

1

3

4

3

3

4






find操作:一只向上找知道发现set[i]=i找到最后的树根 最好情况o(1),最坏退化到链表

union操作:直接把另一棵树的树根j,set[j]=另一棵树的树根


public class Disjoint_Set2 {
	
	
	 public static int find (int i,int []array)
	    {
	    	while(array[i]!=i)
	    	{
	    		i=array[i];
	    	}
	    	return i;
	    }
	    
	    public static void union(int i,int j,int []array)
	    {
	    	int min,max;
	    	if(i


我的源码是很简单,随意的把一颗树的根接到另一颗树下,通过分析,最坏情况find是退化到链表的时间复杂度上,如何优化?


避免最坏情况的方法:

方法:将深度小的树合并到深度大的树
实现:假设两棵树的深度分别为h1和h2, 则合并后的树的高度h是:
max(h1,h2), if h1<>h2.
h1+1, if h1=h2.
效果:任意顺序的合并操作以后,包含k个节点的树的最大高度不超过logk

1            22

       
最坏情况Θ(log N)                                                                               Θ(1)


外加一个数组来记录树的高度





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值