并查集的压缩优化
并查集有两个基本操作:
查:查找x、y的root
并:如果x、y的root不相同,修改y的root为x的root
数据结构parents[x]代表x的父级,如果不压缩,最坏情况下【n个元素串成一串】找到root的时间复杂度是O(n)。
优化:将parents扁平压缩为两层,root节点是第一层,同一集合中其他的节点是第二层,它们的parents都是root。这样,查找root的时间复杂度始终是O(1)
代码实现:
int findRoot(int x)
{
if(x != parents[x])
{
parents[x] = findRoot(parents[x]);
return parents[x];
}
else
return parents[x];
}
利用了递归,集合中所有节点的parents都变成了root。
非递归写法:
int findRoot(int x)
{
int temp = x;
while(temp != parents[temp])
{
temp = parents[temp];
}
int root = temp;
while(x != parent[x])
{
int p = parent[x];
parent[x] = root;
x = p;
}
return root;
}