并查集

来源:互联网 发布:今天eia数据公布 编辑:程序博客网 时间:2024/06/04 23:06
在一些有N个元素的集合应用问题中,通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找某个元素在哪个集合中。这类题目特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述,往往在空间上过大,尤其是时间复杂度极高,根本就不可能在比赛规定的运行时间内计算出结果,只能采用一种全新的抽象的特殊数据结构--并查集。初始时n个元素分属n个不同集合:查:检查两个元素是否同一集合;并查集主要处理不相交集合的合并与查找问题。实现方法:1、用编号最小的元素标记所在集合:    定义一个数组set[1...n],set[i]表示i所在的集合。    代码:
find1(x){    return set[x];}Merge1(a,b){        i = min( find1(a),find1(b));     j = max(find1(a),find1(b));     for (k = 1; k <= N; k++) {          //需要查询全部元素         if (set[k] == j)            set[k] = i;     }}
2、每一个集合用一个有根数表示:    定义一个数组set[1...n]        set[i]=i,表示i是集合本身,而且是树的根。        set[i]=j, j是i的父节点。    代码:
find2(x){   r = x;   while (set[r] != r)      r = set[r];   return r;}merge2(a, b){    if (a<b)       set[b] = a;    else       set[a] = b;}
优化:路径压缩:每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快    1、找到根节点    2、修改路径上所有节点,将其全部指向根节点。    代码:
find4(x){      if (set[x] == x)          return x;          else           return(set[x]=find4(set[x]));   }
0 0
原创粉丝点击