连接(关系)的传递性
一、并查集
二、集合的存储结构
查(属于哪个集合):找其根结点
并:把一个根连上另一个根
三、集合运算
查找某元素所在集合:
1.查找某元素(若顺序则可简化为下标)
2.查找该元素所在集合
注意://错误写法:for(;i>=0;i=T[i].parent);
必须检查到自己的parent是负数为止,不然输出永远是负的数量
路径压缩:
将找到的根结点变成这条路径中的所有结点的父结点。
//将父结点的根Find(T[i])变成当前结点的根T[i]
//T[i]=Find(T[i]);
多次查找效率明显提高
//或者这样理解
int Findi(int i){
if(S[i]<0) return i;
S[i]=Findi(S[i]);
return S[i];
}
将两个元素所在集合合并:
1.找到两元素所在集合的根结点Root1,Root2
2.另一个根节点指向另一个
S[Root2].parent=Root1;(S[Root2]=Root1)
//值变,元素在数组中位置不变
按秩归并:
为改善查找性能,可以采用小的集合合并到大的集合中(修改Union函数)
要比较大小,需要知道每个集合的元素个数(利用根结点存储的负值)
1:按规模归并(根结点存储的是树的规模)
2:按高度归并(根结点存储的是树的高度)