简体   繁体   中英

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;
}

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM