Search code examples
c#algorithmmergesort

How to fix this implementaion of the Merge Sort in c#


I've read the CLRS and tried to implement the recursive merge sort algorithm . cant see what the error is but everytime i run it gives me an "Index out of bounds error "

i've been trying for 5h now

static public void MergeSort(int[] input, int IndexStanga, int IndexDreapta)
{
    if (IndexStanga < IndexDreapta)
    {
        int IndexMijloc = (IndexDreapta + IndexStanga) / 2;
        MergeSort(input, IndexStanga, IndexMijloc);
        MergeSort(input, IndexMijloc + 1, IndexDreapta);

        Merge(input, IndexStanga, IndexDreapta, IndexMijloc);
    }
}

static public void Merge(int[] input, int stanga, int dreapta, int mijloc)
{
    int lungDR = 0;
    int lunST = 0;
    lungDR = dreapta - mijloc;
    lunST = mijloc - stanga + 1;
    int[] valDreapta = new int[lungDR + 1];
    int[] valStanga = new int[lunST + 1];

    valDreapta[valDreapta.Length - 1] = int.MaxValue;
    valStanga[valStanga.Length - 1] = int.MaxValue;

    int i = 0;
    int j = 0;

    for (i = stanga; i <= mijloc; i++) valStanga[i] = input[i];

    for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }

    i = 0;
    j = 0;

    for (int k = 0; k < input.Length; k++)
    {
        if (valStanga[i] <= valDreapta[j]) //error out of bounds 
        {
            input[k] = valStanga[i];
            i++;
        }
        else
        {
            input[k] = valDreapta[j];
            j++;
        }
    }
}

Solution

  • Fixes noted in comments below. First fix for moving data from input to valStanga. Second fix for the range on merging back to input. The parameters for merge are in an unusual order, first, last, middle. Normally the order is first, middle, last.

    Comments: The program will have issues if the array to be sorted contains elements equal to max integer. It would be more efficient to do a one time allocation of a working array, rather than allocate new sub-arrays on every call to merge. The copy operations can be avoided by changing the direction of merge with each level of recursion.

        int i = 0;
        int j = 0;
    
        for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
        for (i = 0; i < lunST; i++) { valStanga[i] = input[i + stanga]; }      // fix
    
        i = 0;
        j = 0;
    
        for (int k = stanga; k <= dreapta; k++)                                // fix
        {
            if (valStanga[i] <= valDreapta[j])