提交 63857d77 authored 作者: Thomas Mueller's avatar Thomas Mueller

Partial sort

上级 9a2b7e25
......@@ -163,16 +163,15 @@ public class SortOrder implements Comparator<Value[]> {
* @param limit the limit
*/
public void sort(ArrayList<Value[]> rows, int offset, int limit) {
if (rows.isEmpty())
if (rows.isEmpty()) {
return;
}
if (limit == 1 && offset == 0) {
rows.set(0, Collections.min(rows, this));
return;
}
Value[][] arr = rows.toArray(new Value[rows.size()][]);
Utils.topNSorted(arr, offset, limit, this);
Utils.sortTopN(arr, offset, limit, this);
for (int i = 0, end = Math.min(offset + limit, arr.length); i < end; i++) {
rows.set(i, arr[i]);
}
......
......@@ -436,60 +436,67 @@ public class Utils {
}
/**
* Will find top limit values in array using given comparator and place them on positions like if
* full array sort occur. Does not guarantee any sort order of these top elements.
* Find the top limit values using given comparator and place them as in a
* full array sort, in descending order.
*
* @param array the array.
* @param offset the offset.
* @param limit the limit.
* @param cmp the comparator.
* @param comp the comparator.
*/
public static <X> void topN(X[] array, int offset, int limit, Comparator<? super X> cmp) {
partialQuickSort(array, 0, array.length - 1, cmp, offset, offset + limit - 1);
public static <X> void sortTopN(X[] array, int offset, int limit,
Comparator<? super X> comp) {
partitionTopN(array, offset, limit, comp);
Arrays.sort(array, offset, Math.min(offset + limit, array.length), comp);
}
/**
* The same as {@link #topN(Object[], int, int, Comparator)}} but guarantees sort order of
* found top elements.
* Find the top limit values using given comparator and place them as in a
* full array sort. This method does not sort the top elements themselves.
*
* @param array the array.
* @param offset the offset.
* @param limit the limit.
* @param cmp the comparator.
* @param array the array
* @param offset the offset
* @param limit the limit
* @param comp the comparator
*/
public static <X> void topNSorted(X[] array, int offset, int limit, Comparator<? super X> cmp) {
topN(array, offset, limit, cmp);
Arrays.sort(array, offset, Math.min(offset + limit, array.length), cmp);
private static <X> void partitionTopN(X[] array, int offset, int limit,
Comparator<? super X> comp) {
partialQuickSort(array, 0, array.length - 1, comp, offset, offset + limit - 1);
}
private static <X> void partialQuickSort(X[] array, int low, int high, Comparator<? super X> cmp, int start, int end) {
if (low > end || high < start || (low > start && high < end))
private static <X> void partialQuickSort(X[] array, int low, int high,
Comparator<? super X> comp, int start, int end) {
if (low > end || high < start || (low > start && high < end)) {
return;
}
int i = low, j = high;
X pivot = array[low + (high - low) / 2];
// use a random pivot to protect against
// the worst case order
int p = low + MathUtils.randomInt(high - low);
X pivot = array[p];
int m = (low + high) >>> 1;
X temp = array[m];
array[m] = pivot;
array[p] = temp;
while (i <= j) {
while (cmp.compare(array[i], pivot) < 0) {
while (comp.compare(array[i], pivot) < 0) {
i++;
}
while (cmp.compare(array[j], pivot) > 0) {
while (comp.compare(array[j], pivot) > 0) {
j--;
}
if (i <= j) {
X x = array[i];
array[i] = array[j];
array[j] = x;
i++;
j--;
temp = array[i];
array[i++] = array[j];
array[j--] = temp;
}
}
if (low < j)
partialQuickSort(array, low, j, cmp, start, end);
if (i < high)
partialQuickSort(array, i, high, cmp, start, end);
if (low < j) {
partialQuickSort(array, low, j, comp, start, end);
}
if (i < high) {
partialQuickSort(array, i, high, comp, start, end);
}
}
/**
......
......@@ -42,7 +42,7 @@ public class TestUtils extends TestBase {
testGetNonPrimitiveClass();
testGetNonPrimitiveClass();
testReflectionUtils();
testTopN();
testSortTopN();
}
private void testWriteReadLong() {
......@@ -62,37 +62,27 @@ public class TestUtils extends TestBase {
}
}
private void testTopN() {
private void testSortTopN() {
Random rnd = new Random();
Comparator<Integer> cmp = new Comparator<Integer>() {
Comparator<Integer> comp = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
for (int z = 0; z < 10000; z++) {
Integer[] arr = new Integer[1 + rnd.nextInt(500)];
for (int i = 0; i < arr.length; i++) {
arr[i] = rnd.nextInt(50);
}
Integer[] arr2 = Arrays.copyOf(arr, arr.length);
int offset = rnd.nextInt(arr.length);
int limit = rnd.nextInt(arr.length);
Utils.topNSorted(arr, offset, limit, cmp);
Arrays.sort(arr2, cmp);
Utils.sortTopN(arr, offset, limit, comp);
Arrays.sort(arr2, comp);
for (int i = offset, end = Math.min(offset + limit, arr.length); i < end; i++) {
if (!arr[i].equals(arr2[i])) {
System.out.println(offset + " " + end);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr2));
fail();
fail(offset + " " + end + "\n" + Arrays.toString(arr) + "\n" + Arrays.toString(arr2));
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论