![算法设计与问题求解(第2版):计算思维培养](https://wfqqreader-1252317822.image.myqcloud.com/cover/909/32517909/b_32517909.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
2.2.6 并查集
并查集(Disjoint set或者Union-find set)是一种树结构,常用于处理一些不相交集合(Disjoint Sets)的查询(Find)及合并(Union)问题,包含两种基本操作:
☢ Find(x)——查询元素x属于哪一个子集。
☢ Union(x, y)——将元素x和元素y所在的子集合并成同一个集合。
在图2-26中,查询操作Find(D)和Find(F)分别返回对应树的根结点A和H,合并操作Union(D, F)则把D和F所在的两棵树合并,如右图所示。
![](https://epubservercos.yuewen.com/9BC028/17545850807267206/epubprivate/OEBPS/Images/cutq_58_29828_l.jpg?sign=1739529996-b6H6VQy7u4sP3UTadkb69XSTdw4TbxeJ-0-d2bbb017323f7b28f7252b6c20dddc2a)
图2-26 并查集的Find和Union操作
并查集森林将每个集合以树表示,树中的每个结点保存着到其父结点的引用,根结点没有父结点,其引用赋值为-1。每个集合选定一个固定的元素作为该集合的代表,称为代表元素,代表元素则用于标识整个集合。每个集合的代表元素即集合的根结点。并查集森林可以采用双亲表示法,如图2-27所示,father数组下标代表元素的序号,其值表示父结点的序号。元素4的父结点是5,因此 father[4]=5。
![](https://epubservercos.yuewen.com/9BC028/17545850807267206/epubprivate/OEBPS/Images/cutq_58_48428_m.jpg?sign=1739529996-DhibhVlKVBG1giTstv5wUu6cvaIhz1Nx-0-a77a1d51df49e7283ff6187c4c8f6079)
图2-27 集合树的双亲表示法
根据并查集森林的定义,我们可以设计Find(x)算法,即从结点x开始不断向上遍历,直到根结点为止。显然,该算法的时间复杂性是线性的。
程序2-7 查询操作Find算法实现
![](https://epubservercos.yuewen.com/9BC028/17545850807267206/epubprivate/OEBPS/Images/cutq_58_3872_l.jpg?sign=1739529996-csaEcLilRrPBpViE8fub1EZ8hyZxzIeZ-0-62795bccbd36b66dcdb61265a0ee7338)
类似地,我们也可以设计Union(x, y)算法,即先查询x所在集合的代表元素xRoot,查询y所在集合的代表元素yRoot,如果代表元素不相同,则把yRoot指向xRoot。
程序2-8 合并操作Union算法实现
![](https://epubservercos.yuewen.com/9BC028/17545850807267206/epubprivate/OEBPS/Images/cutq_58_9564_l.jpg?sign=1739529996-ql0i1xn2ig0zmp8VBAfxpXpijwAreIgo-0-40c657cf089acfd7892827e44bce0bf3)
这是并查集森林最基础的表示方法以及Find和Union操作。注意,在数据不平衡时,大量的Union操作可能导致集合树的深度比较深,Find操作的效率降低。