数据结构——二十二、并查集(王道408)

文章目录

前言

本文介绍了并查集(Disjoint Set)的逻辑结构、存储实现和优化方法。主要内容包括:1)用互不相交的树表示集合,通过查操作(Find)和并操作(Union)实现集合操作;2)使用双亲表示法存储结构,给出初始化、查、并的代码实现;3)提出优化方案,通过小树合并到大树的方式控制树高,将查操作的时间复杂度从O(n)优化到O(log₂n)。并查集是一种高效处理不相交集合的数据结构,适用于需要频繁查询和合并集合的场景。文章还总结了并查集的重要考点和知识点框架。
代码在文章开头,有需要自取🧐

一.逻辑结构------"集合"

1.全集

2.子集与森林

  • 将各个元素划分为若干个互不相交的子集

  • 森林。森林是m(m≥0)棵互不相交的树的集合

  • 同一子集中的各个元素,组织成一棵树用于表示各个子集之间互不相交的关系

二.用互不相交的树,表示多个"集合"

1.查操作

如何"查"到一个元素到底属于哪一个集合?

答:从指定元素出发,一直寻找它的父结点,直至找到根节点,根节点代表了其属于哪一棵树
如何判断两个元素是否属于同一个集合?

答:分别查到两个元素的根,判断根节点是否相同即可

2.并操作

如何把两个集合"并"为一个集合?

答:让一棵树成为另一棵树的子树即可
注:并查集(Disjoint Set)是逻辑结构------集合的一种具体实现,只进行"并"和"查"两种基本操作

三.代码实现并查集

1.存储结构------双亲表示法

1.定义

2.代码

c 复制代码
#define SIZE 13
int UFSets[SIZE];	//集合元素数组

3.图例

2.初始化

初始状态:所有的元素都是一个一个独立的结点

c 复制代码
//初始化并查集
void Initial(int S[]){
	for(int i=0; i<SIZE; i++)
		S[i]=-1;
}

3.查操作

1.定义

  • Find--"查"操作:确定一个指定元素所属集合

2.代码

c 复制代码
//Find"查"操作,找x所属集合(返回x所属根结点)
//x表示这个元素的数组下标
int Find(int S[], int x){
	while(S[x]>=0)//循环寻找x的根
		x=S[x];
	return x; //根的S[]小于0
}

3.时间复杂度

4.并操作

1.定义

  • Union--"并"操作:将两个不相交的集合合并为一个

2.代码

c 复制代码
}
//Union"并"操作,将两个集合合并为一个
//Root1和Root2是要合并的两个集合的根结点
void Union(int S[], int Root1, int Root2){
	//要求Root1与Root2是不同的集合
	if(Root1==Root2) return;
	//将根Root2连接到另一根Root1下面
	S[Root2]=Root1;
}

3.时间复杂度

四.使用Union操作优化并查集

可以看出查这个操作的最坏的时间开销直接和树的高度的相关,如果我们想要优化这个并查集的效率的话,那我们能否在构造这个树的时候让这棵树别长得太高

1.优化思路

  • 在每次Union操作构建树的时候,尽可能让树不长高

    ①用根节点的绝对值表示树的结点总数

    ②Union操作,让小树合并到大树

  • 例子

    • A这棵树有6个结点,因此存为-6
    • C这棵树有2个结点,因此存为-2
    • C这棵树有5个结点,因此存为-5

2.代码展示

c 复制代码
//Union"并"操作,小树合并到大树
void Union(int S[], int Root1, int Root2){
	if(Root1==Root2) return;
	if(S[Root2]>S[Root1]){//Root2结点数更少
		S[Root1] += S[Root2]; //累加结点总数
		S[Root2]=Root1; //小树合并到大树
	}else{
		S[Root2] += S[Root1]; //累加结点总数
		S[Root1]=Root2; //小树合并到大树
	}
}

3.优化后影响

  • 该方法构造的树高不超过 ⌊ l o g 2 n ⌋ + 1 \lfloor log₂n\rfloor+1 ⌊log2n⌋+1
  • Union操作优化后,Find操作最坏时间复杂度:O(log₂n)

五.知识回顾与重要考点

结语

二更😉
想要查看更多章节?请点击一、数据结构专栏导航页

相关推荐
驯狼小羊羔14 分钟前
学习随笔-require和import
前端·学习
奔跑吧邓邓子29 分钟前
【C语言实战(77)】STM32实战:解锁传感器数据采集的C语言奥秘
c语言·stm32·开发实战·传感器数据采集
小刘爱玩单片机32 分钟前
【stm32简单外设篇】- 土壤湿度传感器
c语言·stm32·单片机·嵌入式硬件
2301_7965125238 分钟前
Rust编程学习 - 问号运算符会return一个Result 类型,但是如何使用main函数中使用问号运算符
开发语言·学习·算法·rust
deng-c-f1 小时前
Linux C/C++ 学习日记(47):dpdk(八):UDP的pps测试:内核 VS dpdk
学习
小龙报1 小时前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
摇滚侠1 小时前
Spring Boot3零基础教程,Reactive-Stream 发布订阅写法,笔记104 笔记105
java·spring boot·笔记
d111111111d1 小时前
STM32外设学习--TIM定时器--编码器接口
stm32·嵌入式硬件·学习
喜欢吃燃面1 小时前
Linux:make自动化和实战演练
linux·学习
晨非辰1 小时前
【数据结构初阶】--从排序算法原理分析到代码实现操作,参透插入排序的奥秘!
c语言·开发语言·数据结构·c++·算法·面试·排序算法