Disjoint Set

本文探讨了QuickFind和QuickUnion算法的优化,特别是通过path compression和union by rank技巧提升效率。介绍了如何在find函数中应用path compression,以及如何在union函数中使用rank来平衡树结构,以降低查找和合并操作的时间复杂度。适合理解和实践并查集在实际问题中的高效应用。
摘要由CSDN通过智能技术生成

一个可用graph连接表示的array,每个element都代表一个node

常用函数:find(x) && union(x,y)

find(x) 的功能是找出x所对应的root node

union(x,y)的功能是把x和y连在一起,即将y的root node改为x的root node

Quick Find:

把每个element的值设为root node

 int find(int x) {
        return root[x];
    }

 void unionSet(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            for (int i = 0; i < root.size(); i++) {
                if (root[i] == rootY) {
                    root[i] = rootX;
                }
            }
        }
    }

find(x) -- O(1)

union(x,y) -- O(n)

Quick Union:

把每一个element的值设为parent node

Quick Union

find(x) -- O(n)(最坏情况下是O(n),即每一个node连接上一个node,要traverse n次才能找到root node)

union(x,y) -- O(n) (依然是最坏情况)

Quick Union 比 Quick Find更加efficient,因为我们最常用到的添加关系的function为union,而添加n个元素quick find 需要O(n^2)的time complexity,而 quick union最坏情况下才是O(n^2),大多数时候是<O(n^2)的,所以添加union会更快

Optimization of disjoint set:

  • The find function – optimized with path compression: 

        --每次find一个元素的root node时,都会顺便更新往上找的这一条path上所有元素的root node,即如果一个disjoint set是2->3->4->5, find(5)会把2,3,4,5的root node都变为2.

这样可以减少下次用find的时间

实现方式:

int find(int x) {
    if (x == root[x]) {
        return x;
    }
    return root[x] = find(root[x]);
}
  • The union function – Optimized by union by rank:
  • 把较短的set连到较长的set上去,使得tree的分布最平均。 这样find()的时候需要traverse的element就会变少,time complexity降低

void unionSet(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY) {
        if (rank[rootX] > rank[rootY]) {
            root[rootY] = rootX;
        } else if (rank[rootX] < rank[rootY]) {
            root[rootX] = rootY;
        } else {
            root[rootY] = rootX;
            rank[rootX] += 1;
        }
    }
}

Tips:这里的rank代表了height of the tree。 所以当两个height相同的set连在一起,那势必整个tree height至少+1

运用disjoint set:

主功能不变,根据目的增加UnionFind  的函数,或者改变find(),unionSet()一点,例如把void unionSet(x,y)改为bool unionSet(x,y)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值