Search code examples
javasortingstack-overflowmergesort

java.lang.StackOverflowError in MergeSort


public class MergeSort
{
public static double[] MergeSort(double[] a){
    if(a.length < 1){
        return new double[0];
    }
    else if(a.length == 1){
        return a;
    }
    else{
        double[] l = Teiler(a, false);
        double[] r = Teiler(a, true);
        return Fueger(MergeSort(l), MergeSort(r));
    }
}
...
}

public static double[] Fueger(double[] a, double[] b): returns an array of doubles containing all numbers from a and b in correct order.

public static double[] Teiler(double[] a, boolean l): returns half of the elements (the first half, if l is false, second half, if l is true)

Fueger and Teiler work perfectly well, but MergeSort always gives java.lang.StackOverflowError, even though the recursion should be terminates as soon as the array is empty or just contains one element. What is the problem?

Thanks for your help

Here is Fueger:

public static double[] Fueger(double[] a, double[] b){
    double[] hilf = new double[a.length + b.length];
    int i = 0;
    while((a.length != 0) && (b.length != 0)){
        if(a[0] < b[0]){
            hilf[i] = a[0];
            a = Weg(a);
        }
        else{
            hilf[i] = b[0];
            b = Weg(b);
        }
        i++;
    }
    if(a.length != 0){
        for(double x : a){
            hilf[i] = x;
            a = Weg(a);
            i++;
        }
    }
    if(b.length != 0){
        for(double x : b){
            hilf[i] = x;
            b = Weg(b);
            i++;
        }
    }
    return hilf;
}

Teiler:

public static double[] Teiler(double[] a, boolean r){
    double[] hilf;
    int x = 0;
    if(r == false){
        hilf = new double[(int) a.length / 2];
        for(int i = 0; i < a.length / 2; i++){
            hilf[x] = a[i];
            i ++;
        }
    }
    else{
        hilf = new double[(int) (a.length / 2) + 1];
        for(int i = a.length / 2; i < a.length; i++){
            hilf[x] = a[i];
            i ++;
        } 
    }
    return hilf;
}

Solution

  • The problem is in the Teiler method. Consider a list of length 2, the else branch creates a list of length 2 rather than 1 (even though it fills only the first element). Consequently, trapping the recursion in an endless loop. You can easily fix this issue by adding the last element only if the length is odd:

    public static double[] Teiler(double[] a, boolean r){
       double[] hilf;
       int x = 0;
       if(r == false){
           hilf = new double[(int) a.length / 2];
           for(int i = 0; i < a.length / 2; i++){
               hilf[x] = a[i];
               i ++;
           }
       } else{
           hilf = new double[(int) (a.length / 2) + (a.length % 2)];
           for(int i = a.length / 2; i < a.length; i++){
               hilf[x] = a[i];
               i ++;
           } 
       }
       return hilf;
    }