数据结构与算法分析:不相交集类

不相交集类是解决等价问题的一种有效数据结构,实现简单,代码很少,速度快。

基本思想

等价关系
对于任意一对元素a,b∈S,定义关系~ ,使得a~b要么为true要么为false
1.(自反性)对于所有的a∈S,a~a
2.(对称性)a~b当且仅当b ~ a
3.(传递性)若a~b且b ~ c则a ~ c

等价类 :对于元素a∈S,等价类是S的一个子集,包含所有与a有等价关系的元素。S的每个成员恰好在一个等价类中

不相交集:设有N个集合的类,每个集合含有一个不同元素,所有的元素两两不等价,那么这些集合不相交

union/find算法:对于这些不相交集,有两种操作方式:find,返回等价类的名字;union,将两个等价类合并
实现这个算法最简单的操作是以森林的方式给出,这个森林隐式地位于一个数组中
数组的角标代表元素,角标上的值代表元素的父节点,默认只有一个元素的等价类根为-1

算法实现

public class DisjSets 
{
	private int[] s;
	
	//初始化
	public DisjSets(int numElement)
	{
		s =  new int[numElement];
		for(int i = 0; i < numElement; i++)
			s[i] = -1;
	}
	
	//按秩求并:根的数据为秩-1
	public void union(int root1, int root2)
	{
		if(s[root2] < s[root1])  //root2更深
			s[root1] = root2;    //roo2成为新的根
		else
		{
			if(s[root2] == s[root1])
				s[root1]--;      //相同则树的高度增1
			s[root2] = root1;    //root1成为新的根 
				
		}
	}

	//路径压缩的find
	public int find(int x)
	{
		if(s[x] < 0)             //x为根
			return x;
		else 
			return s[x] = find(s[x]);
								 //x所在路径的所有节点的父节点都是根
								 //s[x] = s[s[x]] = ... = root
	}
}

可以看出,每个方法近乎是以常数的时间运行

不相交集类的一个例子是迷宫的生成,这里不再赘述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值