这是我到目前为止编写的代码:
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)
有人可以帮忙吗?哪里出错了?
答案 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)
将对从索引left
到right - 1
的所有元素进行排序,randomizePivot(lo, hi)
会返回lo
到hi - 1
等范围内的随机数。
这是一个也在java标准库中使用的约定。
答案 2 :(得分:0)
大小为24的列表(Java中的数组)的索引不能为24,因为索引将从零开始。这意味着大小为10的数组将具有索引0到9而不是1到10.这里看起来像索引24被请求而列表只有索引0到23。