并查集动画演示
用父指针把元素串成森林,两次优化让它近乎常数。
键盘:← → 单步 ·空格 播放/暂停 · R 重置 ·Home/End 到两端
并查集回答的问题只有一个:这两个元素是不是同一伙的。它把每个集合画成一棵父指针树,成员顺着 parent 一路向上到根,根相同就连通。这一页用「孩子在左、树根在右」的层次布局演示 union 与 find 全过程,每个节点标注自己的父亲或秩,union 由 rank 决定谁挂到谁下面,合并完立刻刷新森林形状。
它的两个优化分工明确、缺一不可:按秩合并防的是「挂错方向」——把矮树挂到高树下,避免树高失控,代价是每次合并多看一眼元数据;路径压缩防的是「老路太长」——find 走过一遍就把查询链上的节点直接改挂到根,第二次再问近乎一步到位。开关一拨,两种结局同屏对比:关掉压缩,E、C 永远经 D 中转;打开压缩,链条塌成星形,均摊代价逼近常数(准确说是反阿克曼函数)。Kruskal 判环、好友关系连通这类问题,都是它的主场。
并查集演示怎么用
- 拨压缩开关:路径压缩是页顶的一个开关档:开着时每个多跳的 find 结束会追加「直挂树根」步骤,边集合当场重画;关掉则森林保持原样。
- 读方向:连线一律画成孩子指向父亲,图上越靠右越接近根;节点下方文字写明「父:X」或「根·秩r」,双向核对不怕看走眼。
- 看合并依据:每次 union 先各走一遍 find 亮出两个代表元与各自的秩,再按「矮挂高、等秩加一」的规则落子,note 直接引用数字。
- 核对分量:末步按连通分量分组染色,右侧 note 报出分量划分,可拿去和手算的分组比对。
常见问题
既然有按秩合并,为什么还要路径压缩?
按秩只约束树的高度上界(对数级),常数与访问局部性都不算好;路径压缩让「走过的路」一次性变短,把均摊代价压到 α(n)。一个防新增畸形、一个清历史欠账,是正交的两笔优化,合用才有近乎 O(1) 的表现。
按秩和按大小合并有什么区别?
秩是树高的上界估计,等秩才加一,多数合并不动它;大小是子树结点数,谁大当爹。两者复杂度同一量级,按秩的元数据更新更省,按大小的直观性强一点,实现上常可互换。
为什么不用 DFS 判连通?
DFS 适合「图已给定、一次问完」;并查集强在动态:边一条条来、连通性随时问,还支持在线合并。Kruskal 每加一条边问一次、每问一次都可能合并,换成 DFS 每问都要重扫图,代价完全不同。
演示编号 C04无需安装,手机端同样可用按 Ctrl + K 搜工具与演示