Java 导致堆栈溢出的快速排序算法

Java 导致堆栈溢出的快速排序算法,java,quicksort,stack-overflow,Java,Quicksort,Stack Overflow,已解决:张贴在本评论末尾 我不断地得到这个错误,我找不到任何解释它为什么会发生 Exception in thread "main" java.lang.StackOverflowError at java.util.Random.nextDouble(Random.java:444) at java.lang.Math.random(Math.java:716) at assignment6quickSort.M6.qsAlgorithm(M6.java:50) at assignment6q

已解决:张贴在本评论末尾

我不断地得到这个错误,我找不到任何解释它为什么会发生

Exception in thread "main" java.lang.StackOverflowError
at java.util.Random.nextDouble(Random.java:444)
at java.lang.Math.random(Math.java:716)
at assignment6quickSort.M6.qsAlgorithm(M6.java:50)
at assignment6quickSort.M6.qsAlgorithm(M6.java:60)
at assignment6quickSort.M6.qsAlgorithm(M6.java:60)
at assignment6quickSort.M6.qsAlgorithm(M6.java:60)
我一直在谷歌上疯狂地搜索,似乎没有人有过同样的问题,或者我愚蠢到寻找正确的东西(完全可能)

无论如何,我正在创建随机数来为一个普通的快速排序找到一个轴心数,几个小时前它工作了一些次,但现在我每次都会遇到这个错误

求你了,我很沮丧。。。呵呵! 我到底做错了什么? 这怎么会导致溢出

我的密码来了

package assignment6quickSort;

import java.util.ArrayList;
import java.util.List;
import java.util.Comparator;


public class M6 {

    static M6Comparator<Integer> comp = new M6Comparator<Integer>();
    static Integer[] array = new Integer[20];
    static ArrayList qsSorted = new ArrayList();

    public static void main (String[] args) {       

        for (int i = 0; i < array.length; i++) {
            array[i] = (int)(50 * Math.random());
        }

        for (int i: array) {
            System.out.print(i + ", ");
        }

        quickSort(array, comp);
        System.out.println("\n");

        for (Object i: qsSorted) {
            System.out.print(i + ", ");
        }

    }

    static <T> void quickSort(T[] a, Comparator<? super T> comp) {

        ArrayList<T> temp = new ArrayList<T>();
        for (int i = 0; i < a.length; i++) {
            temp.add(a[i]);
        }

        qsSorted = qsAlgorithm(temp, comp);
    }

    static <T> ArrayList<T> qsAlgorithm(ArrayList<T> a, Comparator<? super T> comp) {

        ArrayList<T> L = new ArrayList<T>();
        ArrayList<T> G = new ArrayList<T>();

        if (a.size() <= 1) 
            return a;
        int pivot = (int)Math.random() * a.size();
        T pivotValue = a.get(pivot);
        for (int i = 0; i < a.size(); i++) {
            if (comp.compare(a.get(i), pivotValue) == -1 || comp.compare(a.get(i), pivotValue) == 0) {
                L.add(a.get(i));
            } else {
                G.add(a.get(i));
            }
        }

        L = qsAlgorithm(L, comp);
        G = qsAlgorithm(G, comp);
        L.addAll(G);

        return L;

    }

}
包分配6快速排序;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Comparator;
公共级M6{
静态M6Comparator comp=新的M6Comparator();
静态整数[]数组=新整数[20];
静态ArrayList qsSorted=新ArrayList();
公共静态void main(字符串[]args){
for(int i=0;i静态void quickSort(T[]a,Comparator可能不是真正溢出堆栈的下一个double函数,只是碰巧在每个递归步骤中调用它,因此很可能是达到极限的函数。真正的问题是递归太深(可能是一种错误的基本情况,即停止递归)


看起来
a.size
是你的。确保
a
确实随着递归的每一步而减少。

可能不是下一个双倍函数真正溢出堆栈,只是碰巧你在每个递归步骤中调用它,因此它很可能是达到极限的函数t、 真正的问题是,您的递归太深(可能是一种错误的基本情况,您停止了递归)

看起来
a.size
是您的。请确保
a
确实会随着递归的每一步而减少。

Random不会导致导致堆栈溢出的递归,但确实是

以前的2吨干草捆1:


1提出的代码中的问题是轴包含在递归子问题中。想象一下输入
[x,x]
的情况,在
L
序列中递归选择两个值,因为
x随机并没有导致导致堆栈溢出的递归,但确实如此

以前的2吨干草捆1:



1提出的代码中的问题是轴包含在递归子问题中。想象一下输入
[x,x]
当在
L
序列中递归选择两个值作为
x时,您输入递归调用的次数太多,直到堆栈溢出。问题是,您在主比较循环中达到一个点,即始终将所有元素添加到临时数组“L”,而将无元素添加到“G”,因此递归调用:

L = qsAlgorithm(L, comp);
始终使用与参数相同数量的元素制作:

ArrayList<T> a
arraylista
因此,您永远不会退出第49行中的递归:

if (a.size() <= 1) 
    return a;

if(a.size()您输入递归调用的次数太多,直到堆栈溢出。问题是您在主比较循环中遇到一个点,总是将所有元素添加到临时数组“L”,而将无元素添加到“G”,因此递归调用:

L = qsAlgorithm(L, comp);
始终使用与参数相同数量的元素制作:

ArrayList<T> a
arraylista
因此,您永远不会退出第49行中的递归:

if (a.size() <= 1) 
    return a;

如果(a.size())你确定
((可比)原创)。compareTo(其他);
没有调用自己吗?不……我一点也不确定。不能说我完全理解比较器和泛型。那么……它是在调用自己吗?再看一眼,不,它看起来不像是调用自己。没关系:)你确定
((可比)吗原始)。compareTo(其他);
没有调用自身?不……我一点也不确定。不能说我完全理解比较器和泛型。那么……它是自己调用的吗?再看一眼,不,它看起来不像是对自身的调用。没关系:)但我正在排序的数组只有20个索引。即使我将pivot设置为a.size()/2它给了我一个错误。它怎么可能深入到会导致溢出?该死…听起来很理论化。老实说,我不明白你指的是什么…/;啊哈…是的,我在我使用的伪数组中看到了这一点,我不明白如何连接两个这样的数组列表,不包括子列表中的枢轴这也是一个聪明的优化,因为我们知道它应该在结果中的什么位置(在两个列表之间)。但是我正在排序的数组只有20个索引。即使我将pivot设置为始终为a.size()/2它给了我一个错误。它怎么可能深入到会导致溢出?该死…听起来很理论化。老实说,我不明白你指的是什么…/;啊哈…是的,我在我使用的伪数组中看到了这一点,我不明白如何连接两个这样的数组列表,不包括子列表中的枢轴这也是一个聪明的优化,因为我们知道它应该在结果中的什么位置(在两个列表之间).因为我总是在调用同一个方法之前将a分成两部分,所以我认为它会减少。因为我总是在调用同一个方法之前将a分成两部分,所以我认为它会减少。我真的不确定第二个退出会是什么样子。你的意思是,如果数组必须具有相同的值,它应该退出吗?@PatrikBäckström-注意伪代码
串联(快速排序('less'),'pivot',快速排序('greater'))
。用于排序多个
static <T> ArrayList<T> qsAlgorithm(ArrayList<T> a, Comparator<? super T> comp) {

    ArrayList<T> L = new ArrayList<T>();
    ArrayList<T> E = new ArrayList<T>();
    ArrayList<T> G = new ArrayList<T>();

    if (a.size() <= 1) 
        return a;
    int pivot = (int)Math.random() * a.size();
    T pivotValue = a.get(pivot);
    for (int i = 0; i < a.size(); i++) {
        int v = comp.compare(a.get(i), pivotValue);
        if (v == -1) {
            L.add(a.get(i));
        } else if (v == 0) {
            E.add(a.get(i));
        } else {
            G.add(a.get(i));
        }
    }

    L = qsAlgorithm(L, comp);
    G = qsAlgorithm(G, comp);
    L.addAll(E);
    L.addAll(G);

    return L;

}