Java 快速排序太慢且阵列索引超出边界错误

Java 快速排序太慢且阵列索引超出边界错误,java,indexoutofboundsexception,quicksort,Java,Indexoutofboundsexception,Quicksort,我应该为作业实施快速排序,但我有几个问题。我的代码运行速度比预期的慢得多,我找不到是什么让它慢下来,因为我严格遵循了我们老师的伪代码 此外,当我们提交此代码时,它已经过测试,但我们看不到测试,它说我得到了ArrayIndexOutOfBounds错误,这对我来说没有意义,因为我已经检查了限制是否在正确的范围内 非常感谢您的帮助 public QuickSort() { rand = new Random(); } @Override public void sort(int[] v)

我应该为作业实施快速排序,但我有几个问题。我的代码运行速度比预期的慢得多,我找不到是什么让它慢下来,因为我严格遵循了我们老师的伪代码

此外,当我们提交此代码时,它已经过测试,但我们看不到测试,它说我得到了ArrayIndexOutOfBounds错误,这对我来说没有意义,因为我已经检查了限制是否在正确的范围内

非常感谢您的帮助

public QuickSort() {
     rand = new Random();
}

@Override
public void sort(int[] v) {
    sort(v, 0, v.length-1);     
}

/**
 * Sort an array from two set points, 
 * usually from first index to last.
 */
private void sort(int[] v, int first, int last){
    if(first >= last || last <= first || first < 0 || last < 0)
        return;
    else if(first >= last-10){
        Insertionsort.sort(v, first, last);
        return;
    }           
    else if(first < last && first >= 0){
        int rnd = first+rand.nextInt(last-first+1);
        swap(v, rnd, last);
        int mid = partition(v, first, last);
        sort(v, first, mid-1);
        sort(v, mid+1, last);
    }
}

/**
 * Swaps elements in array around a
 * pivot element.
 * < pivot to the left
 * > pivot to the right 
 */
private int partition(int[] v, int first, int last){        
    int x = v[last];
    int i = first-1;

    for(int j = first; j<last; j++){
        if(v[j] <= x){
            i++;
            swap(v, i, j);
        }
    }

    swap(v, (i+1), (last));

    return (i+1);
}

/**
 * Swap two elements in a list
 */
private void swap(int[] v, int a , int b){
    int temp = v[a];
    v[a] = v[b];
    v[b] = temp;
}

这不是你的快速排序代码,而是你的插入排序

for
循环中,计算循环终止的方法不正确

for (int i = first+1; i < v[last]; i++) {
然后像这样调用它:

public static void sort(int[] v, int first, int last){
Insertionsort.sort(v, first, last);
这样就不需要创建
Insertionsort
的实例来对数组的一小部分进行排序
Insertionsort
只为您做一些事情,而不试图记住任何东西(即,它是无状态的),因此可以使用静态方法

下面是我使用的jUnit测试类:

import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;

public class TestQuicksort {
  @Test
  public void emptyArray() {
    QuickSort q = new QuickSort();
    int[] a = {};
    q.sort(a);
    assertEquals(0, a.length);
  }

  @Test
  public void oneElement() {
    QuickSort q = new QuickSort();
    int[] a = {0};
    q.sort(a);
    assertEquals(1, a.length);
    assertEquals(0, a[0]);
  }

  @Test
  public void oneTwo() {
    QuickSort q = new QuickSort();
    int[] a = {1, 2};
    q.sort(a);
    assertEquals(2, a.length);
    assertEquals(1, a[0]);
    assertEquals(2, a[1]);
  }

  @Test
  public void twoOne() {
    QuickSort q = new QuickSort();
    int[] a = {2, 1};
    q.sort(a);
    assertEquals("Array is " + Arrays.toString(a), 1, a[0]);
    assertEquals(2, a[1]);
  }
}

你自己测试过吗?到目前为止,您的测试用例是什么?如何调用
sort
方法,您的输入在哪里?您的测试用例是什么?您能否发布完整的异常堆栈跟踪。@ErickG.Hagstrom感谢您花时间对其进行测试。我在问题中添加了接口和insertionsort类。我测试了{}、{0}、{1,2}和{2,1}。前三关。{2,1}失败。不过也不例外。我并没有解决它,但下一步我会这样做:根据一个大数据集分析它。找出你大部分时间花在哪里(即在哪个类/方法中)。就个人而言,我想知道您最终创建了多少个
Insertionsort
实例。想想看。你知道静态方法吗?在我的其他类(速度较慢且不使用insertionsort)中,我在时间上也有同样的问题,所以就像你提到的,它可能与Insertsort的安装次数有关。我真的不知道如何测量时间,因为这些方法是递归的。既然我不得不问“你是什么意思”,我想我对静态方法的了解不多,因为如果在主类中使用静态方法,那么这些方法就必须是静态的/是的,那确实相当快。然而,我们应该将我们的解决方案发布到Kattis,在那里运行测试。我无法访问或查看测试,我只能看到我的程序通过所有测试和课程成绩所需的时间。在这里,我的跑步速度比我的课程成绩慢5倍多。我必须对每个方法进行度量。
static
InsertionSort
肯定是一种转移注意力的方法——在现代JVM上创建类非常便宜;在任何情况下都不太可能创造出这么多。然而,对于OP可以使用的良好、简单的单元测试的布局,您得到了+1。这是非常宝贵的建议。
Insertionsort.sort(v, first, last);
import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;

public class TestQuicksort {
  @Test
  public void emptyArray() {
    QuickSort q = new QuickSort();
    int[] a = {};
    q.sort(a);
    assertEquals(0, a.length);
  }

  @Test
  public void oneElement() {
    QuickSort q = new QuickSort();
    int[] a = {0};
    q.sort(a);
    assertEquals(1, a.length);
    assertEquals(0, a[0]);
  }

  @Test
  public void oneTwo() {
    QuickSort q = new QuickSort();
    int[] a = {1, 2};
    q.sort(a);
    assertEquals(2, a.length);
    assertEquals(1, a[0]);
    assertEquals(2, a[1]);
  }

  @Test
  public void twoOne() {
    QuickSort q = new QuickSort();
    int[] a = {2, 1};
    q.sort(a);
    assertEquals("Array is " + Arrays.toString(a), 1, a[0]);
    assertEquals(2, a[1]);
  }
}