数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)

简介: 数据结构学习记录——集合及运算(集合的表示、并查集、树结构表示集合、集合运算、查找函数、并运算)

集合的表示

集合运算概述

交、并、补、差,判定一个元素是否属于某一个集合

并查集

集合并、查某元素属于什么集合

我们最主要关心的就是集合的两个运算,一个是把两个集合并起来;另一个是查找某一个元素是属于哪个集合的。


【例】有10台电脑{1,2,3,...,9,10},已知下列电脑之间已经实现了连接:


1和2、2和4、3和5、4和7、5和8、6和9、6和10


问:2和7之间,5和9之间是否是连通的?

解决思路

(1)将10台电脑看成10个集合{1},{2},{3},...,{9},{10};

(2)已知一种连接“x和y”,就将x和y对应的集合合并;

(3)查询“x和y是否是连通的”就是判别x和y是否属于同一集合。

已经清楚思路了,那么在这样的并查集问题中集合存储要如何实现呢?

  • 可以用树结构表示集合,树的每个结点代表一个集合元素

树结构表示集合

例如,有三个整数集合

S1 = {1,24,7}

S2 = {3,5,8}

S3 = {6,9,10}

存储形式采用数组

数组中每个元素的类型描述为:

typedef int ElementType;  
typedef struct
{
    ElementType Data;
    int Parent;
}SetType;

采用数组存储结点,可以通过下标访问结点,从而快速访问结点和结点信息。

双亲表示法只需要存储每个结点的父结点下标,相比于其他树形结构存储方式,双亲表示法占用的空间更小。

采用数组形式的树形结构双亲表示法存储集合结构的实现相对来说比较简单,易于理解和实现。

但是,

在使用时需要注意数组大小的限制和节点添加、删除的效率问题。此外,双亲表示法对于树形结构的高度有一定的限制,如果树的高度过高,会导致数组过大,空间利用率下降。

 

集合运算

查找函数

查找某个元素所在的集合(用根结点表示

#define MAXN 1000                  /* 集合最大元素个数 */
typedef int ElementType;           /* 默认元素可以用非负整数表示 */
typedef int SetName;               /* 默认用根结点的下标作为集合名称 */
typedef ElementType SetType[MAXN]; /* 假设集合元素下标从0开始 */
 
SetName Find( SetType S, ElementType X )
{    /* 默认集合元素全部初始化为-1 */
    if ( S[X] < 0 ) /* 找到集合的根 */
        return X;
    else
        return S[X] = Find( S, S[X] );  /* 路径压缩 */
}

S 数组用于存储每个元素的父结点,如果一个元素的父结点为负数,则说明该元素为集合的根。


在查找元素 X 所在的集合时,首先判断该元素是否为集合的根,如果是,则直接返回该元素的下标。


如果不是,则通过递归查找该元素的父结点,直到找到集合的根,并将路径上所有结点的父结点都设置为根结点。

在递归返回时,算法还进行了路径压缩的优化。也就是将路径上所有结点的父结点都设置为根结点,避免了后续查找时的重复递归。

路径压缩

路径压缩是一种优化技术,用于加速查找并查集中元素所在集合的过程。


在不进行路径压缩的情况下,每次查找一个元素的根结点时,需要从该元素一直向上遍历到根结点,并将路径上所有结点的父结点都设置为根结点,这样才能保证以后查找该元素所在集合时的效率。


而路径压缩技术的思想是:在递归返回的过程中,将路径上所有结点的父点都设置为根结点。假设要查找元素 X 所在的集合,从 X 开始向上查找其父结点,直到找到集合的根结点,然后将路径上所有节点的父结点都设置为根结点。这样就可以将路径上的所有结点都直接连接到根结点上,从而压缩树的高度,提高查找效率。

并运算

在进行并运算时,要注意

元素所在集合的根结点的 S 值为负数不仅仅单纯为-1,而是用负数大小来表示集合的大小。(例如-7则表示集合中有7个元素)。

void Union( SetType S, SetName Root1, SetName Root2 )
{     /* 这里默认Root1和Root2是不同集合的根结点 */
    /* 保证小集合并入大集合 */
    if ( S[Root2] < S[Root1] )  /* 如果集合2比较大 */
    { 
        S[Root2] += S[Root1];     /* 集合1并入集合2  */
        S[Root1] = Root2;
    }
    else                        /* 如果集合1比较大 */
    {                         
        S[Root1] += S[Root2];     /* 集合2并入集合1  */
        S[Root2] = Root1;
    }

在合并两个集合时,根据两个集合的大小来判断将哪个集合并入另一个集合。这样能使得并起来之后的树的高度尽可能小一点。


如果集合 1 的大小(S[Root1])比集合 2 的大小(S[Root2])小,就将集合 1 并入集合 2 中。


此时,需要将集合 1 的根结点的父结点设置为集合 2 的根结点,并将集合 2 的大小增加集合 1 的大小。



end



目录
相关文章
|
1月前
|
Java
【Java集合类面试二十六】、介绍一下ArrayList的数据结构?
ArrayList是基于可动态扩展的数组实现的,支持快速随机访问,但在插入和删除操作时可能需要数组复制而性能较差。
|
3月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
73 1
|
3月前
|
存储 消息中间件 缓存
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
76 0
|
10天前
|
存储 Java 程序员
【数据结构】初识集合&深入剖析顺序表(Arraylist)
Java集合框架主要由接口、实现类及迭代器组成,包括Collection和Map两大类。Collection涵盖List(有序、可重复)、Set(无序、不可重复),Map则由键值对构成。集合通过接口定义基本操作,具体实现由各类如ArrayList、HashSet等提供。迭代器允许遍历集合而不暴露其实现细节。List系列集合元素有序且可重复,Set系列元素无序且不可重复。集合遍历可通过迭代器、增强for循环、普通for循环及Lambda表达式实现,各有适用场景。其中ArrayList实现了动态数组功能,可根据需求自动调整大小。
26 11
|
18天前
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
|
1天前
|
算法 开发者 计算机视觉
Python并查集:数据结构界的肌肉男,让你在编程路上无所畏惧!
在编程的浩瀚宇宙中,数据结构如同基石,构建了解决问题的坚实框架。而并查集(Union-Find),这位数据结构界的“肌肉男”,以其独特的魅力和强大的功能,让无数开发者在面对复杂关系处理时,都能感受到前所未有的从容与自信。今天,就让我们一同揭开并查集的神秘面纱,看看它是如何成为你编程路上的得力助手的。
6 0
|
2天前
|
算法 程序员 计算机视觉
Python并查集:数据结构界的肌肉男,让你在编程路上无所畏惧!
并查集,一种处理不相交集合合并与查询的数据结构,被誉为编程的“肌肉男”。它提供Find(找根节点)和Union(合并集合)操作,常用于好友关系判断、图像处理、集合合并等。Python实现中,路径压缩和按秩合并优化效率。并查集的高效性能使其成为解决问题的强大工具,助力程序员应对复杂挑战。
8 0
|
1月前
|
存储 安全
集合的特点和数据结构总结
集合的特点和数据结构总结
15 1
|
2月前
|
算法 程序员 图形学
脑洞大开!Python并查集:用最简单的方式,解决最复杂的数据结构问题!
【7月更文挑战第17天】并查集,数据结构明星,处理不相交集合合并与查询。Python实现核心操作:查找与合并。路径压缩优化查找,按秩合并保持平衡。实战应用如图连通性判断,算法竞赛利器。掌握并查集,解锁复杂问题简单解法,照亮编程之旅!
43 10
|
2月前
|
Python
告别低效!Python并查集:数据结构界的超级英雄,拯救你的编程人生!
【7月更文挑战第18天】并查集,数据结构超级英雄,用于不相交集合的合并与查询。Python实现包括初始化、查找根节点和合并操作。应用广泛,如社交网络分析、图论问题、集合划分等。示例代码展示了解决岛屿数量问题,统计连通的“1”单元格数。掌握并查集,提升编程效率,解决复杂问题。
44 6