持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
手把手教学考研大纲范围内树定义,遍历,Huffman,并查集 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出 初心是用最简单的语言描述数据结构
Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会
并查集
并查集介绍
一、概念及其介绍
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。
并查集的思想是:用一个数组表示了整片森林(parent),树的根节点唯一标识了一个集合,我们只要找到了某个元素的的树根,就能确定它在哪个集合里。
二、适用说明
并查集用在一些有 N 个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这个过程看似并不复杂,但数据量极大,若用其他的数据结构来描述的话,往往在空间上过大,计算机无法承受,也无法在短时间内计算出结果,所以只能用并查集来处理。
三、并查集的基本数据表示
如上图 0-4 下面都是 0,5-9 下面都是 1,
表示 0、1、2、3、4 这五个元素是相连接的,5、6、7、8、9 这五个元素是相连的。
再如上图 0、2、4、6、8 下面都是 0 这个集合,表示 0、2、4、6、8 这五个元素是相连接的
1、3、5、7、9 下面都是 1 这个集合,表示 0,1、3、5、7、9 这五个元素是相连的。
Talk is cheap, Show me the Code. 用下面的例题,趁热打铁练习一下层序遍历
并查集例题
思路:
因为并查集是根据森林处理问题
每个集合就是一个森林,此题把两个集合合起来,
换句话说把每个森林的头结连起来,把一个森林的头结点添加到另一个森林头结点的子结点(把两个森林合起来)
#include "iostream"
using namespace std;
int f[10001];
//找a结点的祖先
int getfather(int a) {
if (f[a] == a) { //如果a的父亲是自己,证明a的祖先就是a,返回a
return a;
} else { //如果a的父亲不是自己
//就把a的父亲的父亲求出来赋值给a的父亲,f[a]将变成a的爷爷
// 不断重复调用并赋值给f[a],f[a]将快要变成a的祖先(f[a]不一定是祖先,但是接近祖先)
return f[a] = getfather(f[a]);
}
}
//把 a 与 b 联系起来
void hb(int a, int b) { //a的祖先的父亲变成b的祖先(把两个森林(集合)联系起来)
f[getfather(a)] = getfather(b);
}
int main() {
int n, m, p, a, b;
cin >> n >> m >> p;
for (int i = 1; i <= n; i++) {
f[i] = i;
}
for (int i = 0; i < m; i++) {
cin >> a >> b;
hb(a, b); //合并 a 和 b
}
for (int i = 0; i < p; i++) {
cin >> a >> b;
if (getfather(a) == getfather(b)) { // 看 a b 的祖先是否相等
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
}
return 0;
}