不相交集合
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
简单的不相交集合
#include<iostream>
using namespace std;
#include<string>
#include<vector>
class UnionSet
{
private:
vector<int>pre;
public:
UnionSet()
{
pre.resize(1000);
for (int i = 0; i < 1000; i++)
pre[i] = i;
}
int Find(int x)
{
if (pre[x] == x)
return x;
return Find(pre[x]);
}
void Union(int root1, int root2)
{
root1 = Find(root1);
root2 = Find(root2);
if (root1 != root2)
pre[root1] = root2;
}
};
int main()
{
UnionSet set;
set.Union(10, 20);
set.Union(20, 30);
set.Union(40, 30);
set.Union(10, 50);
cout << set.Find(10) << endl;
cout << set.Find(20) << endl;
cout << set.Find(30) << endl;
cout << set.Find(40) << endl;
cout << set.Find(50) << endl;
return 0;
}
路径压缩的不相交集合
class UnionSet
{
private:
vector<int>pre;
public:
UnionSet()
{
pre.resize(1000);
for (int i = 0; i < 1000; i++)
pre[i] = i;
}
//递归方法
/*int Find(int x)
{
if (pre[x] == x)
return x;
return pre[x] = Find(pre[x]);
}*/
//迭代方法
int Find(int x)
{
int root = x;
while (root != pre[root])
root = pre[root];
int i = x;
while (i != root)
{
int k = pre[i];
pre[i] = root;
i = k;
}
return root;
}
void Union(int root1, int root2)
{
root1 = Find(root1);
root2 = Find(root2);
if (root1 != root2)
pre[root1] = root2;
}
};
按高度合并
class UnionSet
{
private:
vector<int>pre;
vector<int>height;
public:
UnionSet()
{
pre.resize(1000);
height.resize(1000);
for (int i = 0; i < 1000; i++)
{
pre[i] = i;
height[i] = 0;
}
}
int Find(int x)
{
int root = x;
while (root != pre[root])
root = pre[root];
int i = x;
while (i != root)
{
int k = pre[i];
pre[i] = root;
i = k;
}
return root;
}
void Union(int root1, int root2)
{
root1 = Find(root1);
root2 = Find(root2);
if (root1 != root2)
{
if (height[root1] < height[root2])
pre[root1] = root2;
else
{
if (height[root1] == height[root2])
height[root1]++;
pre[root2] = root1;
}
}
}
};
按大小合并
class UnionSet
{
private:
vector<int>pre;
vector<int>size;
public:
UnionSet()
{
pre.resize(1000);
size.resize(1000);
for (int i = 0; i < 1000; i++)
{
pre[i] = i;
size[i] = 1;
}
}
int Find(int x)
{
int root = x;
while (root != pre[root])
root = pre[root];
int i = x;
while (i != root)
{
int k = pre[i];
pre[i] = root;
i = k;
}
return root;
}
void Union(int root1, int root2)
{
root1 = Find(root1);
root2 = Find(root2);
if (root1 != root2)
{
if (size[root1] < size[root2])
{
size[root2] += size[root1];
pre[root1] = root2;
}
else
{
size[root1] += size[root2];
pre[root2] = root1;
}
}
}
};