0

This implementation works reasonably quickly when threshold is set to 0 and it never uses insertion sort, however when i set threshold to seemingly any size 2 or greater it runs at the same speed as just insertion sort. Both sorting functions sort properly so i suspect there is something wrong with the implementation into c++ that is causing it to slow down significantly.

void insertion_sort(double* array, int l, int r)
{
    for (int i = l; i <= r; i++)
    {
        double tmp = array[i];
        int j = i;
        while ((j >= 1) && (array[j - 1] > tmp))
        {
             array[j] = array[j - 1];
             j--;
        }
        array[j] = tmp;
    }
}

void merge(double* arr, double* temp, int l, int m, int r)
{
    int i = l;
    int j = m + 1;
    int k = l;
    while ((i <= m) && (j <= r))
    {
        if (arr[i] < arr[j])
        {
            temp[k] = arr[i];
            i++;
        }
        else
        {
            temp[k] = arr[j];
            j++;
        }
        k++;
    }

        for (; j <= r; j++, k++)
            temp[k] = arr[j];

        for (; i <= m; i++, k++)
            temp[k] = arr[i];

        for (i = l; i <= r; i++)
            arr[i] = temp[i];
}

void mergesort(double* arr, double* temp, int l, int r, int threshold)
{
    if (l < r)
    {
        if ((r - l) <= threshold)
            insertion_sort(arr, l, r);
        else
        {
            int m = (l + r) / 2;
            mergesort(arr, temp, l, m, threshold);
            mergesort(arr, temp, m + 1, r, threshold);
            merge(arr, temp, l, m, r);
        }
    }
}
int main()
{
    double array[100];

    for(int i = 0;i<100;i++)
        array[i] = rand() % 100 +1;

    double * temp = new double[100];
    mergesort(array,temp, 0, 99,10);
    delete[] temp;

    return 0;
}

the main function here doesn't have a large enough array to compare performance but the code used to test my merge sort is a bit to large to post here and pulls data from a text file and i wanted to provide an example of the initial function call.

  • 1
    Make an even smaller set of test data, and use the debugger to step through the code line by line to see what happens. – Some programmer dude Oct 21 '14 at 02:57
  • Your insertion sort looks wrong. In particular, shouldn't `j >= 1` be something more like `j >= i` ? – ooga Oct 21 '14 at 02:58
  • i tested for a situation such as the function calling insertion sort at times that it should not and that is not what seemed to be happening, it was calling insertion sort at the times i was expecting it to – user 2345243512 Oct 21 '14 at 02:59
  • I suppose just punting and doing [something like this](http://pastebin.com/3qPVKGj7) for your insertion sort is off the reservation for this assignment? The binary search feature of `std::upper_bound` is particularly nice for application of a simple insertion-sort algorithm. – WhozCraig Oct 21 '14 at 03:07
  • @ooga ah thats where the problem is, specifically it actually should be `j>=l` (the letter not the number) – user 2345243512 Oct 21 '14 at 03:07
  • @WhozCraig that looks pretty neat, can that implementation be used to sort a sub-array rather than the whole array? at least the code you posted looks to me like it always sorts the whole array – user 2345243512 Oct 21 '14 at 03:11
  • Why do you create array on the stack and temp on the heap? – Neil Kirk Oct 21 '14 at 03:14
  • @user2345243512 I was gonna mention that to you as well. Seemingly every text book or wiki-article out there strives to use three parameters for merge-sort: a base pointer, a "left" index, and a "right" index. Note how that base pointer *never changes*, a crying shame. You can use **that** for your "left" position via pointer math from the caller. Then , all you need is a "length". To answer your question, yes you can use pointer math to position the base address at the left-position, and pass a length of (r-l). I.e. `insertion_sort(arr+l, r-l);` – WhozCraig Oct 21 '14 at 03:14
  • @NeilKirk no good reason really, thats just a symptom of my lack of significant proficiency in c++ i guess – user 2345243512 Oct 21 '14 at 03:18
  • now how do i mark this question as answered? – user 2345243512 Oct 21 '14 at 03:19
  • If @ooga posts an answer you can certainly mark it as accepted (i'll even up-tick it, (nudge nudge, ooga). – WhozCraig Oct 21 '14 at 03:23

1 Answers1

1

The mistake is here:

while ((j >= 1) && (array[j - 1] > tmp))

Instead of J >= 1 it should be j > l (the letter l).

ooga
  • 15,423
  • 2
  • 20
  • 21