![算法设计与问题求解(第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=1738882690-neTQOz6MqiWkvFDbPY0x5IzYq0ahqiPi-0-34f44ee78769b64ab939c6edd5b4ae37)
图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=1738882690-wQwvplvSMT0PZSTTEFz7GlE7Ab0LEytj-0-7fdce5ed504d61d05898de2d2b41f60f)
图2-27 集合树的双亲表示法
根据并查集森林的定义,我们可以设计Find(x)算法,即从结点x开始不断向上遍历,直到根结点为止。显然,该算法的时间复杂性是线性的。
程序2-7 查询操作Find算法实现
![](https://epubservercos.yuewen.com/9BC028/17545850807267206/epubprivate/OEBPS/Images/cutq_58_3872_l.jpg?sign=1738882690-5d6yMNVJlQ8jviP91V9qIGjSWuzUcivC-0-da3b3d53c14d8b7f2662e455c2235eef)
类似地,我们也可以设计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=1738882690-wOY4YwaWzE3gHYNKJO6pOSiOWlWW5Lhw-0-05686f8a4d4a7625e1a7a6b579bf91e7)
这是并查集森林最基础的表示方法以及Find和Union操作。注意,在数据不平衡时,大量的Union操作可能导致集合树的深度比较深,Find操作的效率降低。