【问题标题】:How to get rid off the stackoverflows in my quicksort implementation?如何摆脱我的快速排序实现中的堆栈溢出?
【发布时间】:2015-04-27 22:04:51
【问题描述】:

大家!

我在 Java 中的快速排序实现中遇到了一些 * 问题,对于快速排序的每个递归调用都使用随机枢轴元素,如下面的代码所示。我的问题是我的代码中的三个(!)位置都有 *:

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;

    public QuickSort1()
    {
        randomGenerator = new Random();
    }

    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)
    {
        if(v.length < 2)
            return;            
        else {
            int First = first;
            int Last = last;
            int pivot = v[randomGenerator.nextInt(v.length)];

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

我在调用 sort(int[] v) 时得到的错误信息如下:

java.lang.*Error
    at java.util.Random.nextInt(Random.java:307)
    at QuickSort1.quickSort(QuickSort1.java:37)
    at QuickSort1.quickSort(QuickSort1.java:60)
    at QuickSort1.quickSort(QuickSort1.java:58)

这些消息表明当枢轴元素在 0(包括)和 v.length(不包括)之间的范围内由随机生成器决定时,以及在 quickSort 方法结束时的两个递归方法调用时,这些消息在行处发生堆栈溢出。

奇怪的是,当我想对几个元素进行排序时,实现工作正常。当我想要对 1000 个元素进行排序时,这个实现的问题就开始出现了,然后发生 *Exceptions 并且第 58 行和第 60 行的错误在终端中重复了很多次。

如果能得到一些帮助,我将不胜感激 :)

提前致谢!

/困惑的家伙

【问题讨论】:

  • 您看到的错误消息称为堆栈跟踪。最顶部的行是引发的错误类型。其余的行是从上到下导致错误的方法调用。错误发生在int pivot = v[randomGenerator.nextInt(v.length)];
  • 所以你的意思是它是枢轴,由向量元素的随机索引决定,这就是问题所在?您描述的错误是什么意思? randomGenerator 是否为枢轴提供了一些错误的不合适的值...?
  • 不完全是。查看 *error 是什么,您将开始了解为什么当您必须对 1000 多个元素进行排序时会出现此错误,以及为什么当您拥有较少的元素时不会看到此错误。如果 Stefan Mandel 的回答对您有帮助,那么您应该将其标记为答案。

标签: java quicksort stack-overflow


【解决方案1】:
if(first < Last)
  quickSort(v, first, Last);
if(First < last)
  quickSort(v, First, last);

v 是完整的数组。它永远不会达到小于 2 的长度。要么分区 v,要么将基本情况条件调整为

last - first < 2

【讨论】:

  • 如:if(last-first
  • 在 quickSort 方法的变化开始处?
  • 是的,first 和 last 是要排序的数组的边界。如果这些边界是原子的(0 或 1),则无需排序,您可以返回。
  • 我已经尝试过您的建议,它似乎工作得更好,我不再收到任何错误异常。非常感谢!但是您如何看待由随机索引号决定的枢轴元素?看起来还好吗?
  • 绝对不是问题。 *-Exceptions 来自深度递归,而您的算法具有无限深度递归。
最近更新 更多