mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
Implement Collections#sort
This is really a verbatim translation of Arrays#sort. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
parent
605701e40a
commit
d37b5ada37
@ -33,6 +33,121 @@ public class Collections {
|
||||
shuffle(list, new Random());
|
||||
}
|
||||
|
||||
public static void sort(List list) {
|
||||
sort(list, new Comparator() {
|
||||
public int compare(Object a, Object b) {
|
||||
return ((Comparable) a).compareTo(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final static int SORT_SIZE_THRESHOLD = 16;
|
||||
|
||||
public static <T> void sort(List<T> list, Comparator<? super T> comparator) {
|
||||
int size = list.size();
|
||||
introSort(list, comparator, 0, size, size);
|
||||
insertionSort(list, comparator);
|
||||
}
|
||||
|
||||
private static <T > void introSort(List<T> list,
|
||||
Comparator<? super T> comparator, int begin, int end, int limit)
|
||||
{
|
||||
while (end - begin > SORT_SIZE_THRESHOLD) {
|
||||
if (limit == 0) {
|
||||
heapSort(list, comparator, begin, end);
|
||||
return;
|
||||
}
|
||||
limit >>= 1;
|
||||
|
||||
// median of three
|
||||
T a = list.get(begin);
|
||||
T b = list.get(begin + (end - begin) / 2 + 1);
|
||||
T c = list.get(end - 1);
|
||||
T median;
|
||||
if (comparator.compare(a, b) < 0) {
|
||||
median = comparator.compare(b, c) < 0 ?
|
||||
b : (comparator.compare(a, c) < 0 ? c : a);
|
||||
} else {
|
||||
median = comparator.compare(b, c) > 0 ?
|
||||
b : (comparator.compare(a, c) > 0 ? c : a);
|
||||
}
|
||||
|
||||
// partition
|
||||
int pivot, i = begin, j = end;
|
||||
for (;;) {
|
||||
while (comparator.compare(list.get(i), median) < 0) {
|
||||
++i;
|
||||
}
|
||||
--j;
|
||||
while (comparator.compare(median, list.get(j)) < 0) {
|
||||
--j;
|
||||
}
|
||||
if (i >= j) {
|
||||
pivot = i;
|
||||
break;
|
||||
}
|
||||
T swap = list.get(i);
|
||||
list.set(i, list.get(j));
|
||||
list.set(j, swap);
|
||||
++i;
|
||||
}
|
||||
|
||||
introSort(list, comparator, pivot, end, limit);
|
||||
end = pivot;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void heapSort(List<T> list, Comparator<? super T> comparator,
|
||||
int begin, int end)
|
||||
{
|
||||
int count = end - begin;
|
||||
for (int i = count / 2 - 1; i >= 0; --i) {
|
||||
siftDown(list, comparator, i, count, begin);
|
||||
}
|
||||
for (int i = count - 1; i > 0; --i) {
|
||||
// swap begin and begin + i
|
||||
T swap = list.get(begin + i);
|
||||
list.set(begin + i, list.get(begin));
|
||||
list.set(begin, swap);
|
||||
|
||||
siftDown(list, comparator, 0, i, begin);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void siftDown(List<T> list, Comparator<? super T> comparator,
|
||||
int i, int count, int offset)
|
||||
{
|
||||
T value = list.get(offset + i);
|
||||
while (i < count / 2) {
|
||||
int child = 2 * i + 1;
|
||||
if (child + 1 < count &&
|
||||
comparator.compare(list.get(child), list.get(child + 1)) < 0) {
|
||||
++child;
|
||||
}
|
||||
if (comparator.compare(value, list.get(child)) >= 0) {
|
||||
break;
|
||||
}
|
||||
list.set(offset + i, list.get(offset + child));
|
||||
i = child;
|
||||
}
|
||||
list.set(offset + i, value);
|
||||
}
|
||||
|
||||
private static <T> void insertionSort(List<T> list,
|
||||
Comparator<? super T> comparator)
|
||||
{
|
||||
int size = list.size();
|
||||
for (int j = 1; j < size; ++j) {
|
||||
T t = list.get(j);
|
||||
int i = j - 1;
|
||||
while (i >= 0 && comparator.compare(list.get(i), t) > 0) {
|
||||
list.set(i + 1, list.get(i));
|
||||
--i;
|
||||
}
|
||||
list.set(i + 1, t);
|
||||
}
|
||||
}
|
||||
|
||||
static <T> T[] toArray(Collection collection, T[] array) {
|
||||
Class c = array.getClass().getComponentType();
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Collections {
|
||||
public static void main(String[] args) {
|
||||
testValues();
|
||||
testSort();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -23,4 +26,43 @@ public class Collections {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static void expect(boolean v) {
|
||||
if (! v) throw new RuntimeException();
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> void expectSorted(List<T> list) {
|
||||
for (int i = 1; i < list.size(); ++i) {
|
||||
expect(list.get(i - 1).compareTo(list.get(i)) <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static int pseudoRandom(int seed) {
|
||||
return 3170425 * seed + 132102;
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> int shuffle(List<T> list, int seed) {
|
||||
for (int i = list.size(); i > 1; --i) {
|
||||
int i2 = (seed < 0 ? -seed : seed) % i;
|
||||
T value = list.get(i - 1);
|
||||
list.set(i - 1, list.get(i2));
|
||||
list.set(i2, value);
|
||||
seed = pseudoRandom(seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
public static void testSort() {
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
list.add(Integer.valueOf(i + 1));
|
||||
}
|
||||
;
|
||||
int random = 12345;
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
random = shuffle(list, random);
|
||||
java.util.Collections.sort(list);
|
||||
expectSorted(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user