Fork Join not sorting correctly

312 views Asked by At

I'm trying to do an adaptation of the merge sort using a fork join. I'm using this as a fork/join example so I need to keep it basic. I want to edit the regular merge sort so that when the segment size goes below 101 (100 or less) it will use an insertion sort to sort that segment and then come out of the recursive call and start merging the segments back together. The sort is just simply not working. If I change the order of the invoke and join(to stop other code from running) it works fine so I'm assuming it is because my sorts are running concurrently that it is not correct. For example if I write int mid = (lb+ub)/2; MergeInsertSortQ left = new MergeInsertSortQ(f,lb,mid); MergeInsertSortQ right = new MergeInsertSortQ(f,mid,ub); left.fork(); left.join(); right.fork(); right.join(); merge(f,lb,mid,ub); It sorts fine, but this is esentially sequential so is not really what I'm trying to do.

Here is the code I am using (including a little test in main)

import java.util.concurrent.*;

public class MergeInsertSortQ extends RecursiveAction{

private int[] f;
private int lb, ub;
public MergeInsertSortQ(int f[], int lb, int ub)
{
    this.f = f;
    this.lb=lb;
    this.ub=ub;
}

protected void compute(){
    //Insertion Sort performed when a segment of size
    //100 or less is reached otherwise do merge sort
    if(ub-lb>100)
    {
        int mid = (lb+ub)/2;
        MergeInsertSortQ left = new MergeInsertSortQ(f,lb,mid);
        MergeInsertSortQ right = new MergeInsertSortQ(f,mid,ub);
        invokeAll(left,right);
        left.join();
        right.join();
        merge(f,lb,mid,ub);
    }
    else if(ub-lb>=1)
    {
        for (int i = lb; i<ub;i++)
        {
            int temp = f[i];
            int j = i-1;
            while (j >= 0 && f[j] > temp)
            {
                f[j+1] = f[j];
                j = j-1;
            }
            f[j+1] = temp;
        }
    }
}

protected void merge(int f[], int lower, int middle, int top){
    int i = lower; int j = middle;

    //use temp array to store merged sub-sequence
    int temp[] = new int[top-lower]; int t = 0;

    while(i < middle && j < top)
    {
        if(f[i] <= f[j])
        {
            temp[t]=f[i];i++;t++;
        }
        else{
            temp[t] = f[j]; j++; t++;
        }
    }

    //tag on remaining sequence
    while(i < middle)
    {
        temp[t]=f[i]; i++; t++;
    }
    while(j < top)
    {
        temp[t] = f[j]; j++; t++;
    }

    //copy temp back to f
    i = lower; t = 0;
    while(t < temp.length)
    {
        f[i] = temp[t]; i++; t++;
    }
}

public static void main(String[] args)
{
    //Initialise & print array before sorting
    int A[]=new int[200];
    for(int j=0;j<A.length;j++)
    {
        A[j]=(int)(Math.random()*10000);
        System.out.print(A[j]+" ");
    }
    System.out.println();
    System.out.println("**********************************");
    System.out.println();

    // Do the sort
    ForkJoinPool fjPool=new ForkJoinPool();
    fjPool.invoke(new MergeInsertSortQ(A,0,A.length));

    //Check if array sorted and print
    boolean sorted=true;
    for(int i=0;i<A.length-1;i++)
    {
        System.out.print(A[i] + " ");
        if (A[i]>A[i+1])
        {
            System.out.println();
            System.out.println(A[i]+" is greater than "+A[i+1]+", location "+i);
            sorted=false;
            //break;
        }
    }
    System.out.println();
    if (sorted) System.out.println("The array is sorted!!!");
    else System.out.println("WARNING: The array is NOT SORTED");
}

}

0

There are 0 answers