集合专题
初始化parent集合
const int N = 100;
int parent[N], rank[N];
for(int i = 0; i < N; i++) {
parent[i] = i;
rank[i] = 0; // 为路径压缩做准备
}
寻找祖先结点
int find(int parent[], int x) {
if(parent[x] != x) x = parent[x]; find(parent, x);
return x;
// 不管祖先是不是自己 都是返回的x
}
合并集合
void Union(int parent[], int x, int y) {
int xp = find(parent, x);
int yp = find(parent, y);
if(xp != yp) parent[xp] = yp; // x 并入 y
// 反之则表明两者在同一个集合之中 不进行其他操作
// 路径压缩如下
/**
if(rank[xp] > rank[yp]) parent[xp] = yp;
else if(rank[xp] < rank[yp]) parent[yp] = xp;
else {
parent[xp] = yp; rank[yp] ++;
}
**/
}
开放寻址法
int h[N];
// 如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
int find(int x)
{
int t = (x % N + N) % N; //防止元素负数
while (h[t] != null && h[t] != x)
{ // 如果表中元素不空且不为x 表明发生矛盾 故指针后移
t ++ ;
if (t == N) t = 0;
}
return t;
}
拉链法
int H[N]; //存储的是:指向的第一个结点的下表是多少
int idx;
int node[N], ne[N]; //node存储是的第idx插入的结点的值 ne表示第idx结点的下一个结点位置
void insert(int x) {
int k = (x % N + N) % N;
// 头插法
node[idx] = x; ne[idx] = H[k]; H[k] = idx ++;
}
bool find2(int x) {
int k = (x % N + N) % N;
for(int i = H[k]; i!=-1; i = ne[i]) { // 这个要记住! 第一次见,不好理解
if(node[i] == x) return true;
}
return false;
}
代码与知识点均学习自AcWing:https://www.acwing.com/activity/