5.3 集合及其运算
把一个个的元素看成一个个的集合,如果两个元素之间联通,那么就把这两个集合并起来。
集合我们只关心两个问题,并集和查找,查找就是找到元素所在的那个集合,为此,我们用树来存储集合,用树的根表示该集合,求并集的时候只需要把一棵树接在另一个树上即可。
用树的结构表示集合,在计算机中,我们可以用结构数组来存储这种树,Parent表示该节点的父节点在数组中的位置,根节点的Parent为-1,注意,一个数组可以存好几个不同的集合,也可以只有一个集合。
typedef struct {
ElementType Data;
int Parent;
}SetType;
查找,输入结构数组和要查找的元素,返回元素所在的集合(即该集合树的根节点)
int Find(ElementType x, SetType S[]){
int i;
for(i = 0; i < MaxSize && S[i].Data != x; i++);
if(i >= MaxSize)return -1;
//此处的条件为大于等于0,其实也可以用不等于-1,但是因为后面的并操作会用
//根节点的Parent值存储别的信息,所以不用不等于-1
for(;S[i].Parent >= 0;i = S[i].Parent);
return i;
}
并,parent值用集合元素个数的负值表示(负值小的个数多)
void Union(SetType S[], ElementType x1, ElementType x2){
int root1,root2;
root1 = Find(x1,S);
root2 = Find(x2,S);
if(root1 != root2){
if(S[root1].Parent < S[root2].Parent){
S[root1].parent += S[root2].parent;
S[root2].parent = root1;
}
else{
S[root2].parent += S[root1].parent;
S[root1].parent = root2;
}
}
}