算法导论第21章:并查集

版权声明: https://blog.csdn.net/leelitian3/article/details/82118307

算法分析的一个约定

MAKE-SET的次数为n

MAKE-SET、FIND-SET、UNION的总次数为m

不相交数据集合的链表实现

链表表示一个集合,结点表示一个元素。每个结点都有指向头节点的指针,头结点指向集合的代表元。

MAKE-SET(x):创建一个只有一个结点的链表【O(1)】

FIND-SET(x):元素的结点指向头节点,再指向代表元 【O(1)】

UNION(x,y):较短链表合并至较长链表,短链表的每个结点需要重新指向头结点。【Ω(n)】

时间分析:O(m+nlgn),对于每个结点,最多合并O(lgn)次,总合并次数O(nlgn)。

 朴素的并查集

每棵树代表一个集合,根结点为代表元。约定根节点的祖先为本身。

MAKE-SET(x):创建一个只有一个结点的树【O(1)】

FIND-SET(x):重复查找祖先直到根节点 【O(n)】

UNION(x,y):根指向另一个根【O(1)】

时间分析:FIND-SET(x)太慢了!!

路径压缩(Path Compression)

FIND-SET(x):查找根节点时,顺便把路径上的结点直接指向根节点,将树高变为O(1)

int Find(int x) 
{
    if(x == L[x]) return x;
    int root = Find(L[x]);
    L[x] = root;
    return root;
}

int Find(int x) {
    return x == L[x] ? x : L[x] = Find(L[x]);
}

按秩合并(Union by rank)

UNION(x,y):这里的秩(rank)指的是结点的高度,就是合并两个树的时候,把秩更小的根结点指向秩更大的根节点。就是降低树高,理论上可以加快find-set操作

并查集的时间分析

使用这两种优化后,并查集在最坏的情况下O(m*α(n)) ,α(n) ≤ 4

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/82118307