I have a problem with (no more with stackoverflow (hehe)). Find the algorithm when trying to implement the UnionFind structure algorithm using path compression.
I have a standard ints array, the array can become quite large -> it works fine for up to 60,000,000 elements.
My Union function is as follows:
public void unite(int p, int q) {
if(p >= 0 && p < id.length && q >= 0 && q < id.length){
if (isInSameSet(p, q)) return;
id[find(p)] = find(q);
stevilo--;
}
}
My isInSameSet looks like this:
public boolean isInSameSet(int p, int q) {
if(p >= 0 && p < id.length && q >= 0 && q < id.length)
return find(p) == find(q);
return false;
}
I tried the iterative path in Find:
public int find(int i) {
while (i != id[i]){
id[i] = id[id[i]];
i = id[i];
}
return i;
}
and tail-recrusion:
public int find(int i) {
int p = id[i];
if (i == p) {
return i;
}
return id[i] = find(p);
}
Is there anything I missed in my code? Is there any other approach to such problems?
@edit: adding a constructor to the code:
public UnionFind(int N) {
stevilo = N;
id = new int[N];
for(int i = 0; i < N; i++){
id[i] = i;
}
@ edit2 (better explanation and new results): The problem is not stackoverflow anymore for less than 60,000,000 elements, which is more than enough to solve my problems.
I invoke test unions as follows:
for(i=0;i<id.length-1;i++)
unite(i,i+1)
so the final pairs will be like this:
0:1, 1:2, 2:3, 3:4,..
:)
, 0 (99 100 ), .
, , (0: 0, 1:1, 2: 2, 3: 3). (0: 2, 1: 6, 2: 1, 3: 5,...), .
, , -
id[i] = id[id[i]].