并查集
并查集概念:如下图

并查集的实现
(1)初始化:初始化结点(独立标记每一个结点),初始化rank数组(用于记录子节点的个数)。
void Initial_union_find_set(int n)
{
int i;
for(i = 1;i < n;++i){
father[i] = i;
rank[i] = 1;
}
}
(2)查找:查找当前数值所对应的根节点(如果两数的根节点相同,return node;否则递归遍历)
int find_root_node(int node)
{
if (father[node] != node)
{
father[node] = find_root_node(father[node]);
}
return father[node];
}
(3)合并:合并两个集合(小根接大根,两根相同 return 0;)
int Ally_union_find_set(int p,int q)
{
int root1 = find_root_node(p);
int root2 = find_root_node(q);
if(root1==root2)
{
return 0;
}
if(rank[root1] > rank[root2])
{
father[root2] = root1; //小树连接到大树上,并且权值加至合并后的树上,表示这个树有多少个子节点(压缩存储)
rank[root1] += rank[root2];
}
else
{
father[root1] = root2;
rank[root2] += rank[root1];
}
return 1;
}
源代码:
#include<stdio.h>
#define size 20
int father[size],rank[size];
//并查集初始化操作
void Initial_union_find_set(int n)
{
int i;
for(i = 1;i < n;++i){
father[i] = i;
rank[i] = 1;
}
}
//查找根节点
int find_root_node(int node)
{
if (father[node] != node)
{
father[node] = find_root_node(father[node]);
}
return father[node];
}
//合并并查集
int Ally_union_find_set(int p,int q)
{
int root1 = find_root_node(p);
int root2 = find_root_node(q);
if(root1==root2)
{
return 0;
}
if(rank[root1] > rank[root2])
{
father[root2] = root1; //小树连接到大树上,并且权值加至合并后的树上,表示这个树有多少个子节点(压缩存储)
rank[root1] += rank[root2];
}
else
{
father[root1] = root2;
rank[root2] += rank[root1];
}
return 1;
}
int main()
{
int i, m, x, y;
Initial_union_find_set(size);//初始化操作
printf("Please input the number of the node you want to operate:");
fflush(stdout);
scanf("%d",&m); //m表示操作次数
fflush(stdin);
for (i = 0; i < m; ++i)
{
scanf("%d %d",&x,&y);
int ftp = Ally_union_find_set(x, y);
if (ftp)
{
printf("Union success!\t");
printf("Now %d and %d is related\n",x,y);
fflush(stdout);
}
else
{
printf("Union failed\t");
printf("Because of the generation already exists between %d and %d",x,y);
fflush(stdout);
}
}
return 0;
}
结果分析:

运行结果:

参考资料:
[1].数据结构:用C语言描述/耿国华等著编.–2版.–北京:高等教育出版社,2015.7(2018.1重印)ISBN 978-7-04-043305-0
1万+

被折叠的 条评论
为什么被折叠?



