当前位置: 首页 > news >正文

并查集(上)

1 并查集所包含的方法

int find(a); bool issameset(a,b); void union(a,b);

方法一:int find(a);这个表示是否可以找到这里集合的代表元素
方法二: bool issameset(a,b);这个是表示两个元素是否在一个集合
方法三:void union(a,b);这个表示把两个集合联合在一起

他们均摊的时间复杂度为O(1)

int find(a);


这个方法只需要寻找这个代表于元素是否为同一个,就代表这个两个元素在同一个集合里面,初始化就是把每一个元素进行自环

bool issameset(a,b);
 


这个方法表示为我们利用find方法找到这个最顶端的元素是否一样,一样就是在同一个集合里面

void union(a,b);
 


这个方法表示为,我们合并b和d这两个集合,然后直接把这个b挂到d这个代表元素u的下面
 


这里有一个优化,小的头去挂大的头把f挂到d的下面

2 样例展示方法


下面的数组下标表示每一个元素

0 1合并

首先0的头部变成1了,但是1的头还是1,但是这个0的大小没有改变是因为这个已经没用了,用叉叉表示了,因为此时0不是头了,不再是代表数组

2 3合并

我们不难看到这个就是改变了头,这个3的头变成3了

4 5合并

跟上述一样的

2 4合并

我们不难看出这个就是把这个对应不是代表值的,直接标记为垃圾值

改变对应的头和大小就好了

1 5合并

最后我们就可以得出这个了
 

扁平优化
 


当我们访问a的时候,再返回这个值的时候,所路过的点就直接指向X,这样就是扁平化,这样在下一次再次访问的时候,就可以直接以O(1)的时间复杂度来进行访问了

3 代码实现

#include<iostream>
using namespace std;
const int Max = 1000;
int father[Max];
int binsize[Max];
int binstack[Max];int find(int i) {//收集节点int size = 0;while (i != father[i]) {binstack[size++] = i;i = father[i];}//扁平化while (size > 0) {father[binstack[--size]] = i;}return i;
}bool issameset(int a, int b) {return find(a) == find(b);
}void binunion(int x) {//fx 代表大小     fy 代表大小int fx = find(x);int fy = find(x);if (binsize[fx] >= binsize[fy]) {binsize[fx] += binsize[fy];father[fy] = fx;}else {binsize[fy] += binsize[fx];father[fx] = fy;}
}int main() {}

1 int find(a);
这个就是寻找每一个元素在这个集合的代表元素,返回father数组里面的元素

2 bool issameset(a,b);
这个就是判断两个元素是否在同一个集合里面

3 void union(a,b);
这个就是把带有两个元素的集合进行合并,然后就是改变father数组里面的数字还有就是改变对应的大小,然后另外一个被合并的的size数组里面的数字进行改变

#include<iostream>
using namespace std;
int n;
const int MAX = 100;
int father[MAX];void build() {for (int i = 0; i <= n;i++) {father[i] = i;}
}int find(int i) {if (i != father[i]) {father[i] = find(father[i]);}return father[i];
}bool issameset(int x, int y) {return find(x) == find(y);
}void binunion(int x, int y) {father[find(x)] = find(y);
}int main() {}

这个相比上面的那个代码没有大挂小的写法,栈是利用递归的方式进行书写的

int find(int i) {if (i != father[i]) {father[i] = find(father[i]);}return father[i];
}


这个表示利用递归表示栈的过程,然后就是把那个小挂大的给删除了,不利用这个,一般都是扁平化的时候直接就是直接把后面放到第一个

http://www.xdnf.cn/news/771985.html

相关文章:

  • javaFX eclipse配置
  • Redis数据类型操作命令
  • 考研系列—操作系统:(补充)第七章、输入输出系统
  • 第12次12: 修改和删除收货地址
  • 普通二叉树 —— 最近公共祖先问题解析(Leetcode 236)
  • 专业C++Qt开发服务,助力您的软件项目腾飞!
  • 二叉树的构建与逆构建/二叉查找树与替罪羊树
  • BUUCTF[HCTF 2018]WarmUp 1题解
  • 《人性的弱点》能带给我们什么?
  • C++哈希表:冲突解决与高效查找
  • uni-id-pages login-by-google实现
  • 05.MySQL表的约束
  • 使用免费wordpress成品网站模板需要注意点什么
  • NX847NX855美光固态闪存NX862NX865
  • 向量空间的练习题目
  • 前端高频面试题2:JavaScript/TypeScript
  • SOC-ESP32S3部分:26-物联网MQTT连云
  • 《深度剖析:基于Meta的GameFormer构建自博弈AI游戏代理》
  • 趋势因子均值策略思路
  • 基于STM32的循迹避障小车的Proteus仿真设计
  • hot100 -- 6.矩阵系列
  • Linux(信号)
  • 第十天:Java反射
  • 灵动相册,助力教学:在线教学场景的图片管理利器——仙盟引渡仙君-智能编程——仙盟创梦IDE
  • 通俗理解“高内聚,低耦合”
  • react 生命周期
  • “等待-通知”机制优化(一次性申请)循环等待
  • 电子电路:4017计数器工作原理解析
  • 【Java EE初阶】计算机是如何⼯作的
  • “application/json“,“text/plain“ 分别表示什么