并查集(C语言)

并查集

并查集概念:如下图

在这里插入图片描述

并查集的实现

(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值