首页 > 其他 > 详细

数据结构----并查集 Union-Find

时间:2014-02-27 19:40:28      阅读:516      评论:0      收藏:0      [点我收藏+]

描述:

    并查集是一种描述解决等价关系。能够方便地描述不相交的多个集合。

    支持如下操作    1. 建立包含元素 x 的集合  MakeSet(x)

                              2. 查找给定元素所在的集合 Find(x), 返回所在集合的代表

                              3. 将两个不相交的集合合并 Union(s1, s2)

                               

本文参考《数据结构与算法分析,C语言描述》这本书,利用数组,给出了并查集的一个容易实现的版本。

采用了按秩合并 和 路径压缩 的方法加速。


数据结构:

用树表示一个集合,树的跟节点就是这个集合的代表元素。

并采用一维数组来非显示地模拟这个森林: 

   1. 数组长度是总的集合元素个数; 

   2. s[i] 表示元素 i 的父亲节点; 

   3. 如果 s[i] 是 负数,表示 i 就是代表元素; 并且负数的绝对值表示所在树的高度。(按高度压缩)

在这样的定义下,Find(x) 非常容易实现,只要从元素 x, 不断往上找,直到找到根节点返回即可。


bubuko.com,布布扣

bubuko.com,布布扣

// return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
  if(s[x] < 0)
    return x;
  else
    return Find(s[x], s);
}


按高度合并:

注意到,Find(x) 的复杂度是树的高度。

按高度合并就是通过将 矮的树 合并到 高的树作为其孩子,从而避免树过高。

//Assume root1 and root2 are roots
void SetUnion(DisJointSet s, SetType root1, SetType root2)
{
  if(s[root1] <= s[root2])//root1 is deeper than root2
  {
    if(s[root1] == s[root2])
	  s[root1] --;
    s[root2] = root1;
  }
  else
  {
    s[root1] = root2;
  }
}


路径压缩:

这种方法可以与按高度合并兼容,能够得到较高的效率。

它其实是在 Find(x) 这个函数做文章。

   在搜索 x 所在树的 root 节点的过程中,将中途的节点都指向 root.

看了下图,大家就能明白了。

bubuko.com,布布扣

代码非常简单:

// return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
  if(s[x] < 0)
    return x;
  else
    return s[x] = Find(s[x], s);
}

完整的代码如下:

/* dis-joint-set implemented by L.J. in Nov.11, 2013 */
/* union by height */
#include "disjointset.h"
#include <iostream>
using namespace std;

const   int NumSets = 8;
typedef int DisJointSet[ NumSets + 1];
typedef int SetType;
typedef int ElementType;

void Initialize(DisJointSet s)
{
  for(int i=NumSets; i>0; --i)
    s[i] = 0;
}

//Assume root1 and root2 are roots
void SetUnion(DisJointSet s, SetType root1, SetType root2)
{
  if(s[root1] <= s[root2])//roo1 is deeper than root2
  {
    if(s[root1] == s[root2])
	  s[root1] --;
    s[root2] = root1;
  }
  else
  {
    s[root1] = root2;
  }
}

// return the disjoint set which x belongs to
SetType Find(ElementType x, DisJointSet s)
{
  if(s[x] < 0)
    return x;
  else
    return Find(s[x], s);
}




数据结构----并查集 Union-Find,布布扣,bubuko.com

数据结构----并查集 Union-Find

原文:http://blog.csdn.net/shoulinjun/article/details/19995023

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!