数据结构-并查集 UnionFind

并查集定义:

    并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。

并查集基本操作

并查集——Quick Find:

Quick Find

使用数组来表示存放集合的编号。

Quick Find 成员变量

Quick Find初始化:

Quick Find初始化

Quick Find的查询:

由于是数组存储每个集合的编号,所以查询操作的时间复杂度为O(1)。

find

Quick Find判断某两个元素是否同属于一个集合:

只需要判断 find(p) == find(q)即可。

isConnected

Quick Find的合并操作:

思路:分别找出元素p和元素q的所在的集合编号,如果两个集合编号不相等,说明需要合并。将其中一个集合转换为另一个集合的值。这里需要注意:Quick Find的合并操作的时间复杂度为O(n)。

union

所以,需要对Quick Find进行优化,下面我们使用树来表示一个集合。与其他树不同的是,每个节点指向的是父亲节点。

并查集—— Tree

使用树来表示一个集合。

并查集-树
并查集-树的结构

并查集-树的查询:

这里需要找到第 p 个元素的所在树的根节点,需要遍历,所以时间复杂度为O(h),h 为树的高度。

find

并查集-树的合并:

直接让其中一个的树的根节点指向另一个数的根节点。此时,合并的时间复杂度为O(h)。

union

    至此,并查集就是一个最优方案了吗?其实,并不是。在上面的合并操作中,有一个需要优化的地方,因为未考虑p 和 q 所在树的size,如果直接进行指向, 很可能让元素都在排成一个链表,增加了树的高度,从而影响了性能。所以,要让元素个数少的根节点指向元素个数大的根节点。如下图,操作union(0,2),如果不对树的size进行比较,而直接让 0 元素的根节点 1 指向2,就成了一个链表。

合并前


合并后

并查集优化——size优化:

新增一个数组成员变量int[] sz,来保存每个集合的元素个数。

size优化-结构

新增sz成员变量之后,就可以根据p和q所在树集合的size大小来进行指向了。让元素个数少的树根节点指向元素个数大的树根节点。

size优化

    至此,并查集就是一个最优方案了吗?其实,并不是。合并操作还可以再优化,这个也有一个缺点,那就是当一个宽度很大、深度很小的树 Tree1和 一个宽度很小、深度很大的树 Tree2进行合并,并且Tree1的size > Tree2的size,如果按照size 小的指向size大的原则, 则会把 Tree2头节点指向 Tree1的头节点,导致新的树 Tree1的深度增加了。更合理的合并策略是:深度低的树的根节点指向深度高的树的根节点。如下图,操作union(4,2),如果不对树的深度进行比较,而是根据size进行比较,会让 4 元素的根节点 8 指向 2 元素的根节点 7,就成了一个深度更大的树结构。

合并前
合并后

并查集优化——rank优化:

将数组sz换成数组rank,以 根节点为下标,来表示该跟节点的树的排名(并不完全等于深度),这里说并不完全等于深度,后续会讲到。

rank优化-结构

根据 p 和 q 所在树的根节点,通过rank查找其树的深度,让深度低的树的根节点指向深度高的树的根节点。需要注意的是,当二者rank的值相等时,相当于要把其中一个树当成另一个树的子树,于是需要深度加1。

rank优化-合并

    至此,并查集就是一个最优方案了吗?其实,并不是。查询操可以进行优化,我们的查找操作是通过p 元素,然后一层一层往上查找其根节点的;我们这里其实可以对从p遍历到根节点的路径进行压缩的,先执行 parent[p] = parent[parent[p]],让 p 元素的父亲节点指向其爷爷。

并查集优化——路径压缩:

对某个节点到根节点的遍历路径进行压缩,实现方式是: parent[p] = parent[parent[p]],让 p 元素的父亲节点指向其爷爷。

路径压缩

代码演示:

查询方法


    这里对路径进行了压缩,但是并未影响rank的值,也就是说即使深度变小了,但是rank排名未变。

 至此,并查集才算是一个比较完善的方案了。当然,我们还可以继续优化,就是把压缩路径一下子压缩到树的深度为2的终极情况。但是这样就需要递归处理这样的逻辑,如下图。

find-递归

    由于是递归处理的逻辑,性能上较之前的循环处理要低一点,所以虽然结构上优于之前的树结构,但是总体的性能未必会优于之前的处理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 1 序 2016年6月25日夜,帝都,天下着大雨,拖着行李箱和同学在校门口照了最后一张合照,搬离寝室打车去了提前租...
    RichardJieChen阅读 5,068评论 0 12
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,636评论 0 13
  • 课程介绍 先修课:概率统计,程序设计实习,集合论与图论 后续课:算法分析与设计,编译原理,操作系统,数据库概论,人...
    ShellyWhen阅读 2,233评论 0 3
  • BCHPickerView 功能介绍 用法 使用支持iOS8.0以上 pod 'BCHPickerView' 1....
    B_C_H阅读 622评论 0 1
  • 这里呢,我要讲的是女人,女孩,女生,母的,雌的……都有一个共同的特点,是女性! 那么作为一个女的,最主要的是什么?...
    叔夜君阅读 273评论 0 0