QuickSort太慢而且ArrayIndexOutOfBoundsError

时间:2016-03-01 18:40:03

标签: java indexoutofboundsexception quicksort

我应该为作业实施QuickSort,但我遇到了一些问题。我的代码运行速度比它应该的慢得多,因为我严格遵循我们的老师伪代码,所以我无法找到减慢速度的代码。

此外,当我们提交此代码时,我们已对其进行了测试,但我们无法看到测试,并且说我收到了一个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;
}

我的InsertionSort课程:

public class Insertionsort {

    public Insertionsort() {}

    public static void sort(int[] v, int first, int last){
        int j, toInsert;
        for (int i = first+1; i < v[last]; i++) {
            toInsert = v[i];
            j = i;
            while (j > 0 && v[j - 1] > toInsert) {
                v[j] = v[j - 1];
                j--;
            }
            v[j] = toInsert;
        }
    }
}

我的超类(我们应该在创建不同版本的QuickSort时实现此目的)

public interface IntSorter {

    /**
     * Sorts the array into ascending numerical order.
     */
    void sort(int[] v);
}

1 个答案:

答案 0 :(得分:1)

这不是您的QuickSort代码,而是您的Insertionsort。

for循环中,您错误地计算了循环终止。

for (int i = first+1; i < v[last]; i++) {

在{2,1}的情况下,我发现循环过早终止。但想象一下v[last]是否大于v中的元素数量。是的,ArrayIndexOutOfBounds

故事的寓意:用数百万随机生成的ints进行测试是一个好主意,但用小案例进行测试也会暴露出问题。

至于执行时间,请尝试将static关键字添加到Insertionsort,如下所示:

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