A disjoint-set data structure is a data structure that keeps track of a set of elements partitioned into a number of disjoint subsets. The union-find algorithm is an efficient and fast algorithm that performs many useful operations:
- findSet: Determine which subset a particular element is in.
- unionSet: Join two subsets into a single subset.
- isSameSet: check if 2 elements are in the same subset.
- numDisjointSets: returns the number of disjoint subsets.
- sizeOfSet: size of a subset.
Difficulty level
This exercise is mostly suitable for students
#include <stdio.h>
#include <stdlib.h>
#define M 100
typedef struct
{
int tab[M], p[M], rank[M],setSize[M];
int numSets;
} SET;
SET create(int N)
{
SET S;
int i;
S.numSets = N;
for(i=0;i<N;i++)
{
S.setSize[i]=1;
S.rank[i]=0;
S.p[i]=i;
}
return S;
}
int findSet(int i, SET S)
{
return (S.p[i] == i) ? i : (S.p[i] = findSet(S.p[i], S));
}
int isSameSet(int i, int j, SET S)
{
return findSet(i, S) == findSet(j, S);
}
int numDisjointSets(SET S)
{
return S.numSets;
}
int sizeOfSet(int i, SET S)
{
return S.setSize[findSet(i, S)];
}
void unionSet(int i, int j, SET *S)
{
int x, y;
if (!isSameSet(i, j , *S))
{
S->numSets--;
x = findSet(i, *S);
y = findSet(j, *S);
if (S->rank[x] > S->rank[y])
{
S->p[y] = x;
S->setSize[x] += S->setSize[y];
}
else
{
S->p[x] = y;
S->setSize[y] += S->setSize[x];
if (S->rank[x] == S->rank[y])
S->rank[y]++;
}
}
}
int main()
{
int i;
printf("Assume that there are 5 disjoint sets initially\n");
SET S;
S=create(5);// create 5 disjoint sets
printf("%d\n", numDisjointSets(S)); // 5
unionSet(0, 1, &S);
printf("%d\n", numDisjointSets(S)); // 4
unionSet(2, 3, &S);
printf("%d\n", numDisjointSets(S)); // 3
unionSet(4, 3, &S);
printf("%d\n", numDisjointSets(S)); // 2
printf("isSameSet(0, 3, S) = %d\n", isSameSet(0, 3, S)); // will return 0 (false)
printf("isSameSet(4, 3, S) = %d\n", isSameSet(4, 3, S)); // will return 1 (true)
for (i = 0; i < 5; i++) // findSet will return 1 for {0, 1} and 3 for {2, 3, 4}
printf("findSet(%d, S) = %d, sizeOfSet(%d, S) = %d\n", i, findSet(i,S), i, sizeOfSet(i,S));
unionSet(0, 3, &S);
printf("%d\n", numDisjointSets(S)); // 1
for (i = 0; i < 5; i++) // findSet will return 3 for {0, 1, 2, 3, 4}
printf("findSet(%d, S) = %d, sizeOfSet(%d, S) = %d\n", i, findSet(i, S), i, sizeOfSet(i, S));
return 0;
}
Back to the list of exercises
Looking for a more challenging exercise, try this one !!
Hashing using quadratic probing