使用泛型列表快速排序时索引超出范围的异常

时间:2013-11-26 14:58:33

标签: java list sorting quicksort

这是我到目前为止编写的代码:

import java.util.Collections;
import java.util.Random;
import java.util.List;

public class Sorter<T extends Comparable<T>> {
public void sort(List<T> list) {
    if (list.size() <= 10) {
        insertionSort(list, 0, list.size());
    } else {
        quickSort(list, 0, list.size() - 1);
    }
}

private void quickSort(List<T> list, int leftIndex, int rightIndex) {
    int i = leftIndex;
    int j = rightIndex;
    if (i >= j) { 
        return;
    } else if (j - i <= 10) {
        insertionSort(list, i, j+1);
        return;
    }


    int rand = randomizePivot(j, i);
    T pivot = list.get(rand);
    Collections.swap(list, rand, j);

    while (i < j) {

        while (!list.get(i).compareTo(pivot) && i < j) {
            i++;
        }


        while (!pivot.compareTo(list.get(j)) && i < j) {
            j--;
        }


        if (i < j) {
            Collections.swap(list, i, j);
        }
    }

    list.remove(rightIndex);
    list.add(rightIndex, list.get(j));
    list.remove(j);
    list.add(j, pivot);

    quickSort(list, leftIndex, i - 1);
    quickSort(list, j + 1, rightIndex);
}

private int randomizePivot(int hi, int lo) {
    Random rand = new Random();
    return rand.nextInt(hi - lo + 1) + lo;
}

private void insertionSort(List<T> list, int lo, int hi) {
    for (int i = lo + 1; i < hi; i++) {
        int j = i - 1;
        T elem = list.get(i);
        while (j >= lo && list.get(j).compareTo(elem)) {
            list.remove(j + 1);
            list.add(j + 1, list.get(j));
            j--;
        }
        list.remove(j + 1);
        list.add(j + 1, elem);
    }
}

}

它“工作”九个十分之一。有时它会在这一行给我IndexOutOfBoundsException:

        list.add(rightIndex, list.get(j));

这是枢轴找到其最终位置的部分。在25个项目的列表上的确切错误消息是:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 24, Size: 24
at java.util.LinkedList.checkElementIndex(Unknown Source)
at java.util.LinkedList.get(Unknown Source)

有人可以帮忙吗?哪里出错了?

3 个答案:

答案 0 :(得分:1)

这只能在rightIndex == j时发生 在这里删除最右边的元素,然后在下一步中尝试重新插入它。但是j索引在时间上消失了。

像这样保护它:

if (rightIndex != j) {
       list.remove(rightIndex);
       list.add(rightIndex, list.get(j));
}

答案 1 :(得分:0)

请勿在以下行insertionSort(list, i, j+1);

中添加一个

最简单的方法是更改​​所有方法,使上限始终为独占(例如quickSort(list, left, right)insertionSort(list, left, right)将对从索引leftright - 1的所有元素进行排序,randomizePivot(lo, hi)会返回lohi - 1等范围内的随机数。

这是一个也在java标准库中使用的约定。

答案 2 :(得分:0)

大小为24的列表(Java中的数组)的索引不能为24,因为索引将从零开始。这意味着大小为10的数组将具有索引0到9而不是1到10.这里看起来像索引24被请求而列表只有索引0到23。