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:

  1. findSet: Determine which subset a particular element is in. 
  2. unionSet: Join two subsets into a single subset.
  3. isSameSet: check if 2 elements are in the same subset.
  4. numDisjointSets: returns the number of disjoint subsets.
  5. 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