1.定义:等价类是指相互等价的元素的最大集合。
2.在线等价类
⑴ 初始时,只有n个元素,每个元素属于一个独立的等价类。
⑵需要执行以下操作:
把包含a,b的等价类合并成一个类combina(a,b); 确定哪个类包含元素e,即确定两个元素是否在同一Find(e);不同类返回不同结果。combina(a,b) 等效i=Find(a), j=Find(b); if(i!=j) Union(i,j);
⑶解决方案: 将每个集合(类)描述为一棵树,采用链表的方法来描述树。每个节点必须有一个parent域,但不必有children域 。节点内的数字是其parent域的值,节点外的数字为其索引。索引同时也就是该节点所表示的元素。根节点的 parent域被置为0;
⑷代码实现:
int Find(int e)
{
while(!root[e])
e= parent[e];
returne;
}
高度规则:若树i的高度小于树j的高度,则将j作为i的父节点。
重量规则:若树i的节点数大于树j的节点数,则将j作为i的父节点。
在合并算法中,每个节点上增加 一个布尔域root,若当前节点为跟节点,则其root域为true,
每个根节点的parent域用来保存该树中节点的总数。
voidUnion(int i, int j) //将根为i,j的两棵树进行合并;
{
if(parent[i]< parent[j])
{
parent[j]+= parent[i];
root[i]= false;
parent[i]= j;
}
else
{
parent[i]+= parent[j];
root[j]= false;
parent[j]= i;
}
}
路径压缩:
int Find(int e)
{
Int j = e;
while(!root[j]) //搜索根节点
j =parent[j];
int f =e;
while(f!=j)
{
Int pf= parent[f];
Parent[f]= j;
F =pf;
}
return j;
}
3.离线等价类
离线等价类的输入时元素数目n,关系数目r以及r对关系,问题的目标是吧n个元素分配至相应的等价类中。