【数据结构九】关于集合的合并/查找以及对应优化

81 阅读1分钟

并查集

// 并查集—————
#define UFSets[SIZE]; //集合元素数组

//初始化并查集
void Initial(int S[]){
    for(int i = 0; i < SIZE; i++) {
        S[i] = -1;
    }
}
//Find "查"操作,找x所属集合(返回x所属根结点)
//最坏空间复杂度: O(n)
int Find(int S[], int x){
    while(S[x] >= 0)  //循环找x的根
        x = S[x];
   return x; //根的S[]小于0
}
//Union "并"操作, 将两个集合合并为一个
//时间复杂度:O(1)
void Union(int S[], int Root1, int Root2){
    //要求Root1与Root2是不同的集合
    if(Roo1 == Root2)  return;
    //将根Root2连接到另一根Root1下面
    S[Root2] = Root1;
}

// ————优化:Union: 小树合并到大树
//时间复杂度:O(1)
// 使树高不超过[log2n]+1
void Union(int S[], int Root1, int Root2){
    if(Root1 == Root2) return; 
    if(S[Root2] > S[Root1]){ //Root2结点数更少
        S[Root1] += S[Root2]; //累加结点总数
        S[Root2] = Root1;  //小树合并到大树
    } else {
        S[Root2] += S[Root1]; //累加结点总数
        S[Root1] = Root2; //小树合并到大树
   }
}

总结:

图片.png

//并查集的终极优化
//Find "查"操作优化,先找到根结点,再进行"压缩路径"
int Find(int S[], int x){
    int root = x;
    while(S[root] >= 0) root = S[root]; //循环找到根
    while(x != root){ //压缩路径
        int t = S[x]; //t指向x的父节点
        S[x] = root; //x直接挂到根节点下
        x = t;
    }
    return root; //返回根节点编号
 }

图片.png