<数据结构>并查集与树

作用

查:给定一个元素,查询它在哪个集合内
并:合并两个元素所在的集合

实现思路

对应关系

元素-->结点
集合-->树
多个集合-->森林

用树的根节点作为不同树的标志
合并时只需要将根节点链接

实现

用数组表示树,数组下标表示元素值,数组的值表示该元素对应的父亲结点
father[i] = j : 元素i的父亲结点是j
对于根节点 father[i] = i

<数据结构>并查集与树
图中有两个集合,由两个树表示,根节点分别为元素2,3

查找元素4:
<数据结构>并查集与树

合并元素4,0所在集合:
<数据结构>并查集与树

代码

#include<stdio.h>
const int maxn = 10;
int father[maxn];

void init(int n){  //初始化,开始时,所有元素都不在同一个集合,自身构成集合
    for(int i = 0; i < n; i++)
        father[i] = i;
}

int find(int x){  //查找元素x所在的集合的根节点
    while(x != father[x])
        x = father[x];
    return x;
}
void Union(int x1, int x2){ //合并x1和x2所在的集合
    int Fax1, Fax2;  //分别寻找x1,x2的根节点
    Fax1 = find(x1);
    Fax2 = find(x2);
    if(Fax1 != Fax2)  //如果x1,x2不在同一个集合,合并
        father[Fax1] = Fax2;
}

改进:路径压缩

有时路径过长会导致find函数内部的while循环要执行很多次才能找到根节点

<数据结构>并查集与树

查找0时需要执行多次while循环

对find函数进行改进

int find(int x){
    int a = x;
    while(x != father[x])
        x = father[x];
    //路径压缩
    while(a != father[a]){
        father[a] = x;
        a = father[a];
    }
    return x;
}

压缩后:
<数据结构>并查集与树

上一篇:剑指offer,二叉树的下一个节点


下一篇:Java 中的强制类型转换