10,000,000 を超える要素のコレクションを並べ替えるアルゴリズムを作成する必要があります。というわけで forkjoin クイックソートを書いてみたのですが、入力が大きくなるとコードが崩れてしまいます。まず、テストケースはランダムリストであり、実装で処理できます。次に、順序付けられた数字と同じように、いくつかの極端なケースを試します。コードが失敗します。コードを確認しましたが、理由がわかりません。
これは以下のコードです。
public class ForkJoinSort {
private static int THRESHOLD = 1000;
private static ForkJoinPool pool = new ForkJoinPool();
public static <T extends Comparable<T>> void quickSortFJ(List<T> rawList) {
pool.invoke(new QuickSort<>(rawList));
}
static class QuickSort<T extends Comparable<T>> extends RecursiveAction {
List<T> rawList;
int lo;
int hi;
QuickSort(List<T> rawList) {
this.rawList = rawList;
this.lo = 0;
this.hi = rawList.size() - 1;
}
QuickSort(List<T> rawList, int lo, int hi) {
this.rawList = rawList;
this.lo = lo;
this.hi = hi;
}
@Override
protected void compute() {
if (hi > lo && hi - lo >= THRESHOLD) {
int pivot = partition(rawList, lo, hi);
invokeAll(new QuickSort<>(rawList, lo, pivot - 1),
new QuickSort<>(rawList, pivot + 1, hi));
} else {
quickSort(rawList, lo, hi);
}
}
}
private static <T extends Comparable<T>> int partition(List<T> rawList, int lo, int hi) {
T key = rawList.get(hi);
int index = lo;
for (int i=lo; i<hi; i++) {
if (rawList.get(i).compareTo(key) > 0) {
swap(rawList, index, i);
index ++;
}
}
swap(rawList, index, hi);
return index;
}
private static <T extends Comparable<T>> void swap(List<T> rawList, int left, int right) {
if (left != right) {
T temp = rawList.get(left);
rawList.set(left, rawList.get(right));
rawList.set(right, temp);
}
}
public static <T extends Comparable<T>> void quickSort(List<T> rawList, int lo, int hi) {
if (lo < hi) {
int pivot = partition(rawList, lo, hi);
quickSort(rawList, lo, pivot-1);
quickSort(rawList, pivot+1, hi);
}
}
}
テスト ケースの失敗:
List<Long> longTwoList = new ArrayList<>();
for (long i=0; i!=17000; i++) {
longTwoList.add(i);
}
ForkJoinSort.quickSortFJ(longTwoList);//failed
ForkJoinSort.quickSort(longTwoList, 0, longTwoList.size()-1);//falied
この問題とかなり混乱しています。返信ありがとうございます。