文章目录
并查集
- 集合的运算:交、并、补、差和判断一个元素是否属于某一集合。
- 并查集:集合的合并、判断一个元素是否属于某一集合的操作。
并查集问题中集合如何存储
-
可以用树结构表示集合,每棵树代表一个集合,树的每个节点一个集合的元素。例:
-
怎么更加方便的表示一棵树?答案是用数组。数组元素类型如下:
Typedef struct SetNode{ ElementType Data;//存储数据 int Parent;//存储父节点在数组中的下标;如果本身就是父节点,就用负数表示,负数绝对值的大小可以用来确定这棵树的高度 }SetType;
例:
表示的集合为:
实现
-
查找一个元素在哪个集合
int Find( SetType S[ ], ElementType X ) { /* 在数组S中查找值为X的元素所属的集合 */ /* MaxSize是全局变量,为数组S的最大长度 */ int i; for ( i=0; i < MaxSize && S[i].Data != X; i++) ; if( i >= MaxSize ) return -1; /* 未找到X,返回-1 */ for( ; S[i].Parent > 0; i = S[i].Parent ) ; return i; /* 找到X所属集合,返回树根结点在数组S中的下标 */ }
-
集合的合并
void Union( SetType S[ ], ElementType X1, ElementType X2 ) { int Root1, Root2; Root1 = Find(S, X1); Root2 = Find(S, X2); /* 合并时为了让树的左右子树高度差别不大,只要将高度小的加入高度大的即可 */ if(Root1 != Root2) { if(S[Roo1].Parent > S[Root2].Parent) { S[Roo1].Parent = Root2; } else if(S[Roo1].Parent < S[Root2].Parent) { S[Roo2].Parent = Root1; } else { S[Roo2].Parent = Root1; S[Roo1].Parent--; } } }