并查集
集合的表示
集合运算:交、并、补、差,判定一个元素是否属于某一集合
并查集:集合并、查某元素属于什么集合
并查集问题中集合存储如何实现:
①可以用树结构表示集合,树的每个结点代表一个集合元素
②采用数组存储形式
合并后根为负数,负数代表根,其绝对值代表个数(优化)。
1.查找某个元素所在的集合(用根结点表示)
2.集合的并运算
①分别找到X1和X2两个元素所在集合树的根结点
②如果它们不同根,则将其中一个根结点的父结点指针设置成另一个根结点的数组下标。
为了改善合并以后的查找性能,采用小的集合合并到相对大的集合中。
#define MAXN 1000 /* 集合最大元素个数 */ typedef int ElementType; /* 默认元素可以用非负整数表示 */ typedef int SetName; /* 默认用根结点的下标作为集合名称 */ typedef ElementType SetType[MAXN]; /* 假设集合元素下标从0开始 */ void Union( SetType S, SetName Root1, SetName Root2 ) { /* 这里默认Root1和Root2是不同集合的根结点 */ /* 保证小集合并入大集合 */ if ( S[Root2] < S[Root1] ) { /* 如果集合2比较大 */ //大小集合按照元素个数比较的 S[Root2] += S[Root1]; /* 集合1并入集合2 */ S[Root1] = Root2; } else { /* 如果集合1比较大 */ S[Root1] += S[Root2]; /* 集合2并入集合1 */ S[Root2] = Root1; } } SetName Find( SetType S, ElementType X ) { /* 默认集合元素全部初始化为-1 */ if ( S[X] < 0 ) /* 找到集合的根 */ return X; else return S[X] = Find( S, S[X] ); /* 路径压缩 */ }
C/C++基本语法学习
STL
C++ primer