简体   繁体   English

我的快速排序实现中的Stackoverflow错误

[英]Stackoverflow error in my quicksort implementation

I have extended my codes with having an additional insertion sort algorithm to be chosen by giving the boolean value insertionSort either true or false when constructing a class instance. 我通过在构造类实例时给布尔值insertSort提供true或false来扩展我的代码,并选择额外的插入排序算法。 But when I execute my codes, then i get Stackoverflow error. 但是当我执行我的代码时,我得到Stackoverflow错误。 The codes are as follows: 代码如下:

    import java.util.Random;

    /**
     * Write a description of class QuickSort1 here.
     * 
     * @author (your name) 
     * @version (a version number or a date)
     */
    public class QuickSort1 implements IntSorter
    {
        private int[] v;
        private Random randomGenerator;
        private boolean insertionSort;
        private InsertionSort insertionSorter;

        public QuickSort1(boolean useInsertionSort)
        {
            randomGenerator = new Random();
            insertionSort = useInsertionSort;
            if(insertionSort)
                insertionSorter = new InsertionSort();
        }

        public void sort(int[] v)
        {
            this.v = v;
            if(this.v.length > 0) {
                quickSort(this.v, 0, this.v.length-1);
            }
            else {
                return;
            }
        }

        private void quickSort(int[] v, int first, int last)
        {
            final int startInsertion = 20;
            int First = first;
            int Last = last;
            int pivot = v[randomGenerator.nextInt(v.length)];        

            if(Last-First<2 && !insertionSort)
                return;
            else if(insertionSort) {
                if(pivot >= Last-startInsertion)
                    v = insertionSorter.sort(v);
            }
            else {
                while(First <= Last) {
                    while(v[First] < pivot) {
                        First++;
                    }
                    while(v[Last] > pivot) {
                        Last--;
                        if(Last==0)
                            break;
                    }
                    if(First<=Last) {
                        int temp = v[First];
                        v[First] = v[Last];
                        v[Last] = temp;
                        First++;
                        Last--;
                    }
                }

                if(first < Last

)
                quickSort(v, first, Last);
            if(First < last)
                quickSort(v, First, last);
        }        
    }

    public boolean getInfo()
    {
        return insertionSort;
    }
}

For the alternative insertion algorithm I have implemented a simple class with the following codes: 对于替代插入算法,我实现了一个带有以下代码的简单类:

/**
 * Write a description of class InsertionSort here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class InsertionSort
{
    int[] v;

    /**
     * Constructor for objects of class InsertionSort
     */
    public InsertionSort()
    {
    }

    public int[] sort(int[] v)
    {
        for(int i=1;i<v.length;i++) {
            int temp = v[i];
            int j;
            for(j=i-1;j>=0 && temp<v[j];j--) {
                v[j+1] = v[j];
            }
            v[j+1] = temp;
        }
        return v;
    }
}

The error messages I now get for executing this algorithm for arrays with the size of 10.000-100.000 elements are the following: 我现在为大小为10.000-100.000元素的数组执行此算法所获得的错误消息如下:

java.lang.StackOverflowError
    at java.util.Random.nextInt(Random.java:307)
    at QuickSort1.quickSort(QuickSort1.java:40)
    at QuickSort1.quickSort(QuickSort1.java:68)

The error at line 68 gets reapeted in the terminal a lot of times and it indicates on the first recursive call of the quickSort method. 第68行的错误很多次在终端中被重新分配,并且它在quickSort方法的第一次递归调用中指示。 The line 40 indicates on the line where the pivot element gets decided by Java's randomizing int generator. 线40表示由Java的随机化int生成器决定枢轴元素的行。

I have a strong feeling that this algorithm perhaps cannot be better than it is now since for bigger number of elements, the stack will get empty during the execution for great numbers of elements to be sorted and therefore I perhaps get that StackOverflowError. 我有一种强烈的感觉,这个算法可能不会比现在更好,因为对于更多的元素,堆栈将在执行期间变为空,以便对大量元素进行排序,因此我可能得到StackOverflowError。 But perhaps you have another opinion about this problem? 但也许你对这个问题有另一种看法?

Thanks in advance for helping me out with this :D 在此先感谢帮助我解决这个问题:D

So here we go. 所以我们走了。 I tried your code with a array size of 1,000,000, there 2GB RAM where not enough. 我尝试了一个阵列大小为1,000,000的代码,那里有2GB内存还不够。 So finally the answer will not be satisfying for you, but to point that problem out could be a nightlong program. 所以最后答案对你来说并不令人满意,但要指出问题可能是一个夜间计划。 But I think Stefan Mandel striked the nerve, so if you are interested, feel free to investigate in this direction. 但我认为斯特凡·曼德尔击败了神经,所以如果你有兴趣,可以随意调查这个方向。 But now I won't let you go like that. 但现在我不会让你这样。 I did your homework. 我做了你的功课。 This is working even with the regular heap size. 这甚至与常规堆大小一起工作。 Here is a example how to increase the heap. 是一个如何增加堆的示例。 You'll only need the -Xmx1024 to increase the RAM to 1 GB. 您只需要-Xmx1024即可将RAM增加到1 GB。

public class QuickFooBar {

public static void main(String[] args) {
    Random random = new Random();
    int[] arr = new int[1000000];
    for (int i = 0; i < arr.length; ++i) {
        arr[i] = random.nextInt(1000000);
    }

    QuickSort1 test;
    test = new QuickSort1(false);
    test.setV(arr);
    test.quickSort(0, arr.length - 1);
    arr = test.getV();

    for (int i = 0; i < arr.length; ++i) {
        System.out.println(arr[i] + ", ");
    }
}

} }

public class QuickSort1 {

private int[] arr;
private final boolean insertionSort;


public QuickSort1(final boolean insertionSort) {
    this.insertionSort = insertionSort;
}

public void quickSort(int left, int right) {
    final int startInsertion = 20;
    if (insertionSort) {
        if (((left + right) / 2) >= right - startInsertion) {
            arr = new InsertionSort().sort(arr);
            return;
        }
    }
    int index = partition(left, right);
    if (left < index - 1) {
        quickSort(left, index - 1);
    }
    if (index < right) {
        quickSort(index, right);
    }
}

private int partition(int left, int right) {
    int i = left, j = right;
    int tmp;
    int pivot = arr[new Random(right).nextInt()];
    while (i <= j) {
        while (arr[i] < pivot) {
            i++;
        }
        while (arr[j] > pivot) {
            j--;
        }
        if (i <= j) {
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
            j--;
        }
    };
    return i;
}

public boolean getInfo() {
    return insertionSort;
}

public int[] getV() {
    return arr;
}

public void setV(int[] v) {
    this.arr = v;
}

} }

public class InsertionSort { public class InsertionSort {

public int[] sort(int[] v) {
    for (int i = 1; i < v.length; ++i) {
        int temp = v[i];
        int j;
        for (j = i - 1; j >= 0 && temp < v[j]; j--) {
            v[j + 1] = v[j];
        }
        v[j + 1] = temp;
    }
    return v;
}

} }

    public int[] sort(int[] v) {
    for (int i = 1; i < v.length; ++i) {
        int temp = v[i];
        int j;
        for (j = i - 1; j >= 0 && temp < v[j]; j--) {
            v[j + 1] = v[j];
        }
        v[j + 1] = temp;
    }
    return v;
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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