I apologize for the naming and I agree the implementation is a little C-like. It is in no-way similar to stacks.
Suppose r[0] = 2 and r[1] = 3 and r[2] = 1
***********
This is what CreateSet does:
for the first resource only ie.r[0]
{0}->{1}->{2}
return pointer to begnning of this linked list
***************
send this pointer to JoinSet with pointer to list and value of r[1]
Now r[1] = 3 ie. 0,1,2,3
{0} with 0 = {0,0} ie. data[0]=0,data[1]=0
{0} with 1 = {0,1}
{0} with 2 = {0,2}
{0} with 3 = {0,3}
...
{2} with {3}= {2,3}
deallocate memory for the initial linked list ie {0}{1}{2}
return pointer to new linked list {0,0}...{2,3}
*************
send this pointer to JoinSet again with pointer to new list and value of r[2]
Now r[2] = 1 ie. 0,1
{0,0} with 0 = {0,0,0}data[0]=0,data[1]=0,data[2]=0
{0,1} with 0 = {0,1,0}
{0,2} with 0 = {0,2,0}
...
{2,3} with 0 = {2,3,0}
{0,0} with 1 = {0,0,1}
{0,1} with 1 = {0,1,1}
{0,2} with 1 = {0,2,1}
...
{2,3} with 1 = {2,3,1}
deallocate memory for the initial linked list
ie {0,0}{0,1}{0,2}........{2,3}
return pointer to new linked list {0,0,0}->{0,0,1}..{2,3,0}->...{1,3,2}
{0,0,0}->{0,0,1}..{2,3,0}->...{2,3,1} is the final combination set.
Now, is this an efficient implementation or not.
It's always in the details.