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),所以称为路径压缩。

posted on 2013-05-22 09:17  书上一缕香  阅读(132)  评论(0)    收藏  举报

导航