算法第一章-基础-1.5案例研究:union-find算法
问题陈述:动态连通性。给出一个整数集合,然后输入一列整数对,<p,q>代表p和q是连通的,即在一个连通分量重,最后得到这个整数集合的所有连通分量。
三种算法(第四种属理论):
1)quick-find:用一个数组,数组下标代表所有整数,内容是下标整数所在的连通分量标志,选该连通分量里的某一个整数作为标志。这样,每两个不同的分量做连接操作时,要将其中一个原属的分量遍历修改一遍;做查找操作,只需比较两个分量的数组内容即可得知。
2)quick-union:用一个数组,数组下标代表所有整数,但内容不再是连通分量标志,而是其父节点。父节点就是通过做连接操作得到的,连接就是将一个节点作另一个节点的孩子,那么结果就是一棵树代表一个连通分量;做查找操作时,则要遍历一棵树。
3)加权quick-union:与2)的区别在于,连接操作时,加上一个条件判断,必须将高度较低的树向高度较高的树合并,这样随着树的扩大,整体深度会降低,遍历时就会更快。
4)最优算法(路径压缩):将quick-find算法的思想加入到quick-union中,就是在find操作时,加一个循环将路径上遇到的所有节点都链接到根节点,这样当一棵树的所有非根节点都被链接到根节点后,find操作就可以直接通过判断是否有公共根节点判断是否连通。这种方法不保证每个操作都在常数级别完成,其对加权quick-union也很难改进,这种算法理论研究很复杂。
所以,最优算法仍是加权quick-union。
各种union-find算法性能比较:
算法 | 存在N个触点时成本的增长数量级(最坏情况) | ||
构造函数 | union() | find() | |
quick-find算法 | N | N | 1 |
quick-union算法 | N | 树的高度 | 树的高度 |
加权quick-union算法 | N | lgN | lgN |
使用路径压缩的加权quick-union算法 | N | 很接近但仍没有达到1(均摊成本) | |
理想情况 | N | 1 | 1 |
注:也可以用绘制均摊成本图像的方法观察性能。方法:i表示处理的第i次连接。cost表示访问数组的次数。灰点(i,cost)表示第i次操作成本,红点(i,total/i)表示均摊成本。