V

算法可视化

ZHEN
分享到微博分享到 XGitHub 仓库个人主页
学习工具算法复杂度速查算法学习路径
数据结构数组链表栈队列树堆哈希表图字典树并查集LRU 缓存跳表线段树B+ 树布隆过滤器树状数组
经典排序算法冒泡排序鸡尾酒排序双调排序选择排序插入排序二分插入排序希尔排序归并排序自顶向下归并快速排序三路快排双轴快排堆排序计数排序基数排序桶排序
图算法Dijkstra 最短路Kruskal 最小生成树Prim 最小生成树Bellman-Ford 最短路拓扑排序Floyd 多源最短路强连通分量2-SAT最大流二分图匹配LCA 倍增欧拉路径
动态规划编辑距离0-1 背包完全背包最长公共子序列最长递增子序列硬币找零方案数石子合并旅行商 TSP树形 DP数位 DP换根 DP
回溯与搜索N 皇后子集生成全排列组合总和迷宫寻路岛屿数量单词搜索数独A* 寻路
字符串KMP 字符串匹配Rabin-KarpBoyer-MooreManacher后缀数组LCP / height 数组AC 自动机Z 函数
数学与数论埃氏筛线性筛欧几里得算法快速幂扩展欧几里得中国剩余定理欧拉函数米勒-拉宾FFTPollard's Rho
计算几何凸包旋转卡壳最近点对线段相交扫描线求交
查找二分查找二分边界旋转数组搜索二分答案三分查找

并查集 Union-Find

数据结构 · 极快地维护「谁和谁同组」

什么是并查集

前面的结构大多在存「数据序列」;并查集(Union-Find,又叫不相交集合 DSU)换了个差事——把一堆元素分成若干不相交的组,专门极快地回答两件事:find(x) 这个元素属于哪个组(返回组的代表元、也就是「根」)、union(a,b) 把两个组合并成一个。

实现很巧:每个元素记一个 parent,顺着 parent 一直走到「自己指自己」的那个就是根。同根 = 同组;合并,就是把一个根指到另一个根上。这里有 8 个元素,一开始各自成组。选两个元素点「合并」,或「查根 / 连通?」试试。

亲手试试
01234567

当前 8 个组(连通分量)

选两个元素「合并」,或「查根 / 连通?」试试。一开始 8 个元素各自成组。

朴素的 find 可能要顺着一条长链一路走到根。路径压缩是点睛之笔:find 找到根之后,把沿途每个节点直接指向根,下次再 find 几乎一步到位——并查集能做到近乎 O(1),就靠路径压缩(外加按秩合并)。连成一条链后点「查根」,看箭头怎么齐刷刷改指向根。

并查集在哪里用

连通性判断:朋友圈 / 网络节点是否连通,一个 connected 搞定。
Kruskal 最小生成树:加一条边前,用它判断两端是否已连通(会不会成环)。
岛屿 / 连通分量计数:合并相邻同类,最后数有几个组。
账号合并 / 等价类:把判定为「同一个」的对象并到一起。

它不存序列、只管「同不同组」,是一种用途专一、实现精巧的结构。