#include<stdio.h>
#include<stdlib.h>
#define MaxSize 50
typedef struct ufset {
int parent[MaxSize];
int size;
}UFset;
void CreateUFset(UFset* s, int n) {
int i;
s->size = n;
for (i = 0; i < n; i++) {
s->parent[i] = -1;
}
}
int Find(UFset* s, int i) {
for (; s->parent[i] >= 0; i = s->parent[i]);
return i;
}
void Union(UFset* s,int x, int y) {
s->parent[x] = y;
}
int Find2(UFset* s, int i) {
int r, t, l;
for (r = i; s->parent[r] >= 0; r = s->parent[r]);
if (i != r) {
for (t = i; s->parent[t] != r; t = l) {
l = s->parent[t];
s->parent[t] = r;
}
}
return r;
}
void Union2(UFset* s, int x, int y) {
int temp = s->parent[x] + s->parent[y];
if (s->parent[x] > s->parent[y]) {
s->parent[x] = y;
s->parent[y] = temp;
}
else {
s->parent[y] = x;
s->parent[x] = temp;
}
}
int main() {
UFset* s = (UFset*)malloc(sizeof(UFset));
int i = 0;
CreateUFset(s, 7);
Union2(s, 2, 1);
Union2(s, 3, 4);
Union2(s, 3, 2);
Union2(s, 6, 5);
Union2(s, 3, 6);
for (i = 0; i < s->size;i++) {
printf("%d\t", s->parent[i]);
}
printf("\n%d\n",Find2(s, 5));
for (i = 0; i < s->size; i++) {
printf("%d\t", s->parent[i]);
}
printf("\n%d\n", Find2(s, 5));
for (i = 0; i < s->size; i++) {
printf("%d\t", s->parent[i]);
}
printf("\n%d\n", Find2(s, 1));
for (i = 0; i < s->size; i++) {
printf("%d\t", s->parent[i]);
}
printf("\n%d\n", Find2(s, 1));
for (i = 0; i < s->size; i++) {
printf("%d\t", s->parent[i]);
}
printf("\n%d\n", Find2(s, 0));
for (i = 0; i < s->size; i++) {
printf("%d\t", s->parent[i]);
}
}
-1 2 3 -6 3 6 3
3
-1 2 3 -6 3 3 3
3
-1 2 3 -6 3 3 3
3
-1 3 3 -6 3 3 3
3
-1 3 3 -6 3 3 3
0
-1 3 3 -6 3 3 3
C:\C++程序&C++PrimerPlus\DataStructrue\树与集合-并查集\Debug\树与集合-并查集.exe (进程 19752)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
笔记:
在Union2 进行创建子集时,如果x与y的parent相等,那么Union2(s, x ,y) 就是x为父结点,y为子节点。
在Find2执行的时候会打乱原有树的形状,每查找一次元素,都会使该元素直接连到父节点,使树变得扁平化,方便以后快速查找父节点。
笔记2:
以下为上述main函数下的各个元素的parent的变化情况,随附树的形状示意图。