10. 树--并查集

并查集

定义

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。

存储实现

  • 逻辑结构:使用树结构表示集合,树的每个结点代表一个集合元素
  • 物理结构:采用数组存储,使用双亲表示法(孩子指向双亲)

有三个整数集合:
* S1={1,2,4,7}
* S2={3,5,8}
* S3={6,9,10}

逻辑结构

10. 树--并查集_第1张图片

物理结构

下标 Data Parent
0 1 -1
1 2 0
2 3 -1
3 4 0
4 5 2
5 6 -1
7 8 2
8 9 5
9 10 5

Parent:

  • 负数表示根结点
  • 非负数表示双亲结点的下标

集合的运算

结构定义

typedef struct {
    ElementType Data;
    int Parent;
} SetType;

查找集合

查找某个元素所在的集合,用根结点下标表示

算法:

  1. 从数组中找到该元素的下标
  2. 根据该元素的Parent找到树根结点的下标
// 在数组S中查找值为X的元素所属的集合
int Find(SetType S[], ElementType X) {
    int i;
    for (i = 0; i < MaxSize && S[i].Data != X; i++);    // 将i定位到X所在下标

    if (i > MaxSize) // 未找到X,返回-1
        return -1;

    for (; S[i].Parent >= 0; i = S[i].Parent);  //将i定位到x所在集合的根结点下标

    return i;
}

集合的并运算

基本实现

算法:

  1. 分别找到X1和X2两个元素所在集合树的根结点
  2. 如果它们不同根,则将其中一个根结点的父结点指针设置成另一个根结点的数组下标
void Union(SetType S[], ElementType X1, ElementType X2) {
    int Root1, Root2;

    Root1 = Find(X1);
    Root2 = Find(X2);

    if (Root1 != Root2)     // 当X1和X2不属于同一集合时才需要合并
        S[Root2].Parent = Root1;
}

优化

  1. 在存储时,使用Parent域进行集合数量的记录。例如1个元素,Parent为-1;7个元素Parent为-7
  2. 合并时,采用小的集合合并到相对大的集合中

你可能感兴趣的:(数据结构--读书笔记)