Chinaunix首页 | 论坛 | 博客
  • 博客访问: 314035
  • 博文数量: 60
  • 博客积分: 2781
  • 博客等级: 少校
  • 技术积分: 600
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-23 16:42
文章分类

全部博文(60)

文章存档

2011年(33)

2010年(27)

分类: Python/Ruby

2011-03-20 00:36:09

并查集(Union_Find_Set)是求解连通分量或者等价类快速高效的方法,算法采用了树形的数据结构。

问题描述:已知多对节点的关系,比如(1,2),(2, 3),(4,5),求解其等价类。

问题解析:如果两个节点在同一棵树中,那么可以将其视为等价,如何判断节点在同一棵树中呢?树的根(root)作为树的representative element,可以帮助我们测试节点是否在同一棵树中。
初始化的时候,每个节点都将其本身设置为root,即root[i] = i;随着(u, v)的引入,如何合并树呢?即union(u, v)如何去实现。假如u, v不在同一棵树中,我们可以简单地将 v 所在树的根节点root变成 u 所在树的根节点root的孩子child,这样就完成了 u, v 所在两棵树的合并,以此类推。

通过以上解析,有个问题就是如何获取树的根?这里设置一个全局数组 root[N](root[i]存放第i个节点的长辈,只有当 root[i] == i 的时候才断定 i 就是树根);然后设计一个函数 find(i),该函数返回节点i所在树的根,即find()返回representative element。

综上分析设计并查集的两个操作函数(Python风格),union(u, v) 和 find(i):
  1. '''
  2. Find
  3. '''
  4. def find(i):
  5.     if root[i] == i:
  6.         return root[i]
  7.     else:
  8.         root[i] = find(root[i]) # 路径压缩(path compression),从i节点到根节点路径上的所有节点的root值均被设置成根节点
  9.         return root[i]

  1. '''
  2. Union
  3. '''
  4. def union(u, v):
  5.     if find(u) == find(v): # 同一棵树中
  6.         pass
  7.     else: # 将u树的根节点同时作为v树的根节点,完成了树的合并
  8.         root[find(v)] = find(u)
以上两个函数
union(u, v):合并 u 和 v 所在的集合(呈树形结构)。
find(u):返回 u 所在树形结构集合的根。

给个链接供大家参考:


阅读(3741) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~