并查集
1.并查集问题中集合存储如何实现?
可以用树结构表示集合,每个节点代表一个集合元素
采用数组形式存储
负数表示根结点;非负数表示双亲结点的下标。
数组中每个元素的类型描述为:
typedef struct {
ElementType Data;
int Parent;//相当于指针,表示这个节点的父节点在集合中的位置
} SetType;
2 .集合运算
(1)查找某个元素所在的集合(用根结点表示)
int Find(SetType S[], ElementType X)
{ //在数组S中查找值为X的元素所属的集合
//Maxsize是全局变量,为数组S的最大长度
int i;
for (i=0 ; i < Maxsize && S[i].Data != X; i++); //当S[i].Data = X时,循环结束,i为X的位置下标
if(i >= Maxsize) return -1; //未找到X,返回-1 则i为根节点的下标
for (; S[i].Parent >= 0; i = S[i].Parent); //如果i < Maxsize,寻找父结点,直到S[i].Parent < 0为止(根结点的Parent为-1)
return i; //找到X所属集合,返回树根结点在数组S中的下标
}
(2)集合的并运算
①分别找到X1和X2两个元素所在集合树的根结点;
② 如果它们不同根,则将其中一个根结点的父结点指针设置成另一个根结点的数组下标。
void Union(SetType S[ ], ElementType X1, ElementType X2)
{
int Root1, Root2;
Root1 = Find(S, X1);
Root2 = ind(S, X2);
if (Root1 != Root2) //当x1和x2不属于同一子集时,才需要合并
S[Root2].Parent = Root1;
}