Lec15 - Disjoint Sets
解决连通性问题
较好的方法是只需要记录每个相连元素属于哪个集合,至于如何连接不必关心
数据结构的选择
sets
过于复杂并且耗时高
arrays
另一个想法是:起始将每个元素设置为不同id,只需要记录每个元素所在集合的id,连通只需要将该元素所在集合id改变为目标id即可;检查是否连通只需要检查id是否一致
时间复杂度:
连通方法复杂度还是高了一些
trees
想法是:给每一个元素分配一个父节点来代替id
对于连通操作:可以找到要连通的两个集合的根节点,将一个的根节点设置为另一个
对于检查连通操作:从待检查节点向上寻找父节点,一直找到根节点看是否相同即可
操作本质即寻根并操作根节点
时间复杂度:
优化树结构
我们需要最小化树高
- 将较短的树连接到较长的树下
- 若高度相同,则需要打破相同
规定:总是将更小的树根连接到更大的树上
注意:使用权重衡量才能最小化平均步数,而使用高度衡量只能最小化最坏步数
时间复杂度:
再次进行优化:
查找后将所有节点都连接到根节点上,这样再次查找不必再遍历
这样,随着操作继续,我们的树会变得越来越矮,直到树高为1,这样所有操作都很快
其中\(\alpha(N)\)为逆阿克曼函数,该函数的增长速度特别缓慢,对于具有意义的值x,\(\alpha(x)\)的值始终不大于4,故可以看作常数时间