并查集

定义结构体

typedef int  ElementType ;
typedef int parentType;
struct GNode{
    ElementType data;
    parentType parent;
};
typedef  struct GNode setType[Max];

1、查找元素属于哪个集合
先找到元素x的存储位置->再找x的父亲,一层一层往上找父亲

/*作用:查找元素
传入参数:查找的元素x,已经建立起来的双亲表示法的树s[]*/
ElementType find(ElementType x,setType s[]){
    int i;
    //查找位置
    for(i=0;i<Max && s[i]->data!=x;i++);
    if(i>=Max) return -1;//查找失败
    //找根节点
    for(;s[i]->parent>=0;i=s[i]->parent);
        return i;
}

2、把两个集合并起来
先把两个元素的根节点找到,再把其中一个根节点的父亲指向另一个根节点的数组下标
这里写图片描述

/*作用:将两个集合合并*/
void Union(ElementType x,ElementType y,setType s[]){
    ElementType root1,root2;
    root1=find(x,s);
    root2=find(y,s);
    s[root1]->parent=root2;
}

但是我们能够想象,当无数多个树一直合并合并,会导致树越来越高,查找根节点很费时,所以我们尽量把比较小的连接到表较大的(可能合并后高度改变不大),而且没有必要开辟空间,判断每个节点它是多高,因为我们只关心根节点到底有几个元素

这里写图片描述

所以可以利用根节点的parent,因为-1这个位置还可以刻画信息,这样的话,-1要改成这个集合有多少个元素。代码修改成

/*作用:将两个集合合并*/
void Union(ElementType x,ElementType y,setType s[]){
    ElementType root1,root2;
    root1=find(x,s);
    root2=find(y,s);
    //集合2比较大,这里是负数比较
    if(s[root1]->parent >= s[root2]->parent){
        s[root2]->parent+=s[root1]->parent;//更新集合数量
        s[root1]->parent=root2;
    }else{//集合1大
        s[root1]->parent+=s[root2]->parent;//更新集合数量
        s[root2]->parent=root1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值