并查集

//并查集
#include<stdio.h>
int MaxSize;
typedef int Elemtype;
typedef struct{
    Elemtype data;
    int parent;
}SetType;
//并查集查找
int Find(SetType s[],Elemtype x)
{//MaxSize是全局变量,代表着并查集的大小
    int i;
    for(i=0;i<MaxSize&&s[i].data!=x;i++)//查找x
        if(i>=MaxSize) return -1;       //此条件下代表没找到,返回-1
    for(;s[i].parent>=0;i=s[i].parent); //因为根结点的parent是负数,所以一旦不符合条件退出循环,那么此时的i必是根结点的下标
    return i;
}
//合并
void Union(SetType s[],Elemtype x1,Elemtype x2)
{
    int root1,root2;
    root1=Find(s,x1);//查找x1元素的根结点
    root2=Find(s,x2);//查找x1元素的根结点
    if(root1!=root2){//如果根结点不同,则合并
        s[root1].parent+=s[root2].parent;//当合并后,根结点的parent存储的是合并后树元素的个数的负数
        if(s[root1].parent<s[root2].parent) s[root2].parent=root1;//把个数较少的树接到个数较多的树上,这样使树平衡一点,加快查找效率
        else s[root1].parent=root2;//同理
    }
}
int main()
{
    SetType s[100];
    scanf("%d",&MaxSize);
    for(int i=0;i<MaxSize;i++){
        scanf("%d",&s[i].data);
        s[i].parent=-1;
    }
    Elemtype x1,x2;
    while(scanf("%d%d",&x1,&x2)&&x1)
        Union(s,x1,x2);
    for(int i=0;i<MaxSize;i++)
        printf("%2d%2d\n",s[i].data,s[i].parent);
    return 0;
}
//测试数据
/*
 10
 1 2 3 4 5 6 7 8 9 10
 1 2
 2 4
 4 7
 3 5
 5 8
 6 9
 9 10
 2 5
 0 0
 */
//正确输出
/*
 1-7
 2 0
 3 0
 4 0
 5 2
 6-3
 7 0
 8 2
 9 5
 10 5
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值