Sedgewick Algorithms第一课
Union and find
给定N个object,M个整数对(p,q),其意为p,q连接在一起。那么再给定(x,y),判断x,y是否连接。
解答:
纵观题意,有两个重要操作。
1.给定p,q,将其连接在一起。union(p,q).
2.判断p,q是否已经连接在一起。isconnected(p,q).
由以上思路,发展出以下几种算法:
1.快速查找算法(查找即判断是否连接)
此算法查找效率高,为O(1)复杂度。
算法思路:
使用数组存储N个object,标号从1到N。
union操作:当输入p,q时,将数组里所有标号为p的object改为q。
find操作:直接判断数组里p和q的标号是否相等。
此算法缺陷为:每一对p,q的union操作,其复杂度都需要O(n).如果n对(p,q),其复杂度就达到了O(N^2).效率低。
2.快速并集算法
算法思路:
同样使用数组存储N个object,标号1到N。数组一开始为一个有N棵树的一个森林,每棵树只有根节点。
union操作:当读入p,q时,将p对应的树设为q对应的树的子树。也就是说root(p)指向root(q)。
find操作:判断p和q对应的树的根是否相同。
此算法缺陷为:特殊情况下,数组里可能只形成了一棵深度为N的树。这样其查找效率就为O(N),union也为O(N)。为了避免形成这种一竖串形状的树,要改进形成树的union操作。
改进1:
union操作:当读入p,q时,判断p树和q树的大小,将小的树设为大的树的子树。
为了达到这个目的,另外维护一个sz[]数组,存储当前树中有多少个元素。
改进2:路径压缩
在将小的树设为大的树的子树时,需要定位两棵树的root。考察由p定位root(p)的过程,可以发现,如果已经由p定位到了root(p),那么可以将p直接指向root(p),而不再需要经过中间节点。这也降低了树的高度。由于过程为p…->…->…->root(p), 变为p->root(p),所以称为路径压缩。
浙公网安备 33010602011771号