并查集(2022新增数据结构)

并查集(2022新增数据结构)

逻辑结构

其逻辑结构是集合,各集合见互不相交

森林是m棵互不相交的树的集合
在这里插入图片描述

存储结构(物理结构)

通常采用双亲表示作为并查集的存储结构,因为并查集需要从孩子结点查询其根节点

运算

初始化

#define SIZE 13
int UFSets[SIZE];
// 初始化并查集
void Initial(int S[]){
    for(int i=0;i<SIZE;i++){
        S[i]=-1;  //先让每个结点都自成一派,即S[i]=-1;
    }
}

并(Find)

// 找到x所属集合(返回x所属根节点)
int Find(int S[],int x){
    while(S[x]>=0){
        x=S[x]; //循环寻找x的根
    }
    return x; //根的s[]小于0
}

// 将两个集合合并为一个集合
void Union(int S[],int root1, int root2){
    if(root1==root2) return; //要求root1和root2是不同的集合
    S[root2]=root1;
}

优化Union操作

因为Find的时间复杂度与树的高度h有关,所以我们在合并的时候可以尽可能使树的高度小一些,比如一颗大树和一颗小树合并,我们可以将小数合并到大树上面去,从而使大树的高度h不发生变化,不会增加h,也不会增加Find的时间开销。

//Union ,小树合并成大树  用根节点表示树的结点数 若根为-8,则表明有8个结点
void Union(int S[],int Root1,int Root2){
    if(Root1 == Root2) return;
    if(S[Root2]>S[Root1]){ //因为根的值都为负数,Root2大于Root1,说明Root1中的结点数要多余Root2中的结点数!合并后将Root2与Root1相加即为合并后树中的结点!
        S[Root1]+=S[Root2];
        S[Root2]=Root1;
    }else{
        S[Root2]+=S[Root1];
        S[Root1]=Root2;
    }
}

此时Find的时间复杂度为O(log2n)

并查集的终极优化⭐⭐⭐⭐

int Find(int S[],int x){
    int root=x;
    while(S[root]>=0) root=S[root]; // 先找到x所对应的根结点
    while(x!=root){  //这一步循环直接将待查结点的所有祖先结点全部挂在根节点上了!!
        int t=S[x]; //t指向x的父节点 
        S[x]=root;  //x直接挂到根节点下
        x=t;
    }
    return root;
}
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值