import java.util.*;
import java.util.stream.IntStream;
public class Test1 {
static Random random = new Random();
public static void main(String[] str) {
//10W量级要求每个案例都小于100ms,100W量级要求每个案例都小于1000ms
// test1(100000);
test1(1000000);
//10W量级要求每个案例都小于50ms,100W量级要求每个案例都小于400ms
// test2(100000);
test2(1000000);
}
public static void test1(int num) {
System.out.println("TEST1: " + num);
int cell = 3;
for (int z = 0; z < 6; z++) {
short[] tp = new short[num * cell];
switch (z) {
case 0:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = 0;
tp[i + 1] = (short) (i / (num / 10));
tp[i + 2] = 0;
}
break;
case 1:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = (short) (i >> 2);
tp[i + 1] = (short) i;
tp[i + 2] = 0;
}
break;
case 2:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = (short) ((tp.length - i) >> 2);
tp[i + 1] = (short) (tp.length - i);
tp[i + 2] = 0;
}
break;
case 3:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = (short) random.nextInt(30000);
tp[i + 1] = (short) random.nextInt(30000);
tp[i + 2] = (short) random.nextInt(30000);
}
break;
case 4:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = 0;
tp[i + 1] = (short) (1000 - i / (num / 10));
tp[i + 2] = 0;
}
break;
case 5:
for (int i = 0; i < tp.length; i += cell) {
tp[i] = 0;
tp[i + 1] = 0;
tp[i + 2] = (short) random.nextInt(10);
}
break;
}
long t1 = System.currentTimeMillis();
new SortTest(tp, cell).sort();
System.out.println("case" + z + " cost " + (System.currentTimeMillis() - t1) + "ms");
}
}
public static void test2(int num) {
System.out.println("TEST2: " + num);
for (int z = 0; z < 9; z++) {
long[] tp = new long[num];
switch (z) {
case 0:
for (int i = 0; i < tp.length; i++)
tp[i] = random.nextInt(num);
break;
case 1:
for (int i = 0; i < tp.length; i++)
tp[i] = i;
break;
case 2:
for (int i = 0; i < tp.length; i++)
tp[i] = tp.length - i;
break;
case 3:
for (int i = 0; i < tp.length; i++)
tp[i] = i / (num / 10);
break;
case 4:
for (int i = 0; i < tp.length; i++)
tp[i] = 1000 - i / (num / 10);
break;
case 5:
for (int i = 0; i < tp.length; i++)
tp[i] = i == num / 2 ? 2 : 1;
break;
case 6:
for (int i = 0; i < tp.length; i++)
tp[i] = random.nextInt(10);
break;
case 7:
for (int i = 0; i < tp.length; i++)
tp[i] = random.nextInt(100);
break;
case 8:
for (int i = 0; i < tp.length; i++)
tp[i] = random.nextInt(1000);
break;
}
long t1 = System.currentTimeMillis();
// Arrays.sort(tp); //自带的速度很快,但不满足要求,需求是排下标,而不是排本体
new MergeSort(tp).sort();//可达到要求
// sortByComparator(tp); // case0 600ms左右 其余达标
// intStreamSort(tp); // case0 450ms 左右 其余达标
// new SortTest2(tp).sort();
System.out.println("case" + z + " cost " + (System.currentTimeMillis() - t1) + "ms");
}
}
/**
* TEST2: 1000000
* case0 cost 429ms
* case1 cost 34ms
* case2 cost 14ms
* case3 cost 71ms
* case4 cost 9ms
* case5 cost 76ms
* case6 cost 86ms
* case7 cost 103ms
* case8 cost 138ms
* @param tp
*/
private static void intStreamSort(long[] tp) {
int[] sortedIndices = IntStream.range(0, tp.length).boxed().sorted((i, j) -> {
if (tp[i] < tp[j])
return -1;
if (tp[i] > tp[j])
return 1;
return 0;
}).mapToInt(ele -> ele).toArray();
}
/**
* TEST2: 1000000
* case0 cost 564ms
* case1 cost 31ms
* case2 cost 11ms
* case3 cost 5ms
* case4 cost 7ms
* case5 cost 4ms
* case6 cost 125ms
* case7 cost 137ms
* case8 cost 207ms
* 使用比较器
* @param tp
*/
private static void sortByComparator(long[] tp) {
ArrayIndexComparator comparator = new ArrayIndexComparator(tp);
Integer[] indexes = comparator.createIndexArray();
Arrays.sort(indexes, comparator);
}
public static <T extends Object> List<T[]> splitArray(T[] array, int splitSize) {
int numberOfArrays = array.length / splitSize;
int remainder = array.length % splitSize;
int start = 0;
int end = 0;
List<T[]> list = new ArrayList<T[]>();
for (int i = 0; i < numberOfArrays; i++) {
end += splitSize;
list.add(Arrays.copyOfRange(array, start, end));
start = end;
}
if (remainder > 0) {
list.add(Arrays.copyOfRange(array, start, (start + remainder)));
}
return list;
}
static class SortTest {
int cell;
short[] tp; //把这个排序,每cell个一组
public SortTest(short[] tp, int cell) {
this.cell = cell;
this.tp = tp;
}
void sort() {
// System.out.println(JSON.toJSONString(tp));
int sort = tp.length / cell;
heapSort(sort);
// System.out.println(JSON.toJSONString(tp));
}
public void heapSort(int size) {
int lengthOfArray = size;
// 创建堆
for (int i = (lengthOfArray - 1) / 2; i >= 0; i--) {
heapify(lengthOfArray, i);
}
// 排序
for (int i = lengthOfArray - 1; i >= 0; i--) {
// Swap the root node with last node
swap(i, 0);
heapify(i, 0);
}
}
public void heapify(int index, int i) {
// 初始化
int parentIndex = i;
int leftChild = (2 * i) + 1;
int rightChild = (2 * i) + 2;
// 比较左子值
if (leftChild < index && compare(leftChild, parentIndex) > 0) {
parentIndex = leftChild;
}
// 比较右子值
if (rightChild < index && compare(rightChild, parentIndex) > 0) {
parentIndex = rightChild;
}
if (parentIndex != i) {
swap(parentIndex, i);
heapify(index, parentIndex); // 递归调用
}
}
public void sort(int size) {
int index;
for (int i = 1; i < size + 1; i++) {
index = 0;
for (int j = 1; j <= size + 1 - i; j++) {
if (compare(j, index) >= 0) {
index = j;
}
}
//交换在位置array.length - i 和 index(最大值)上的两个元素
swap(size - i, index);
}
}
void swap(int p1, int p2) {
int i1 = p1 * cell;
int i2 = p2 * cell;
short s1 = tp[i1];
short s2 = tp[i1 + 1];
short s3 = tp[i1 + 2];
tp[i1] = tp[i2];
tp[i1 + 1] = tp[i2 + 1];
tp[i1 + 2] = tp[i2 + 2];
tp[i2] = s1;
tp[i2 + 1] = s2;
tp[i2 + 2] = s3;
}
int compare(int p1, int p2) {
int i1 = p1 * cell;
int i2 = p2 * cell;
long v1 = (long) (tp[i1] << 4) | (tp[i1 + 1] << 2) | tp[i1 + 2];
long v2 = (long) (tp[i2] << 4) | (tp[i2 + 1] << 2) | tp[i2 + 2];
return v1 == v2 ? 0 : v1 > v2 ? -1 : 1;
}
}
static class SortTest2 {
long[] vals;
int[] indexes; //vals的下标位置,排序排这个,vals不要动,最终 vals[indexes[0]], vals[indexes[1]] ... vals[indexes[n]] 是有序的
int size;
LinkedList<int[]> list = new LinkedList<>();
public SortTest2(long[] vals) {
this.vals = vals;
this.size = vals.length;
indexes = new int[size];
for (int i = 0; i < size; ++i) //初始时,下标是0...n的次序
indexes[i] = i;
}
public void sort() {
list.add(new int[] { 0, size - 1 });
while (!list.isEmpty()) {
int[] n = list.removeLast();
int[] r = quickPos2(n[0], n[1]);
if (r[2] < r[3])
list.add(new int[] { r[2], r[3] });
if (r[0] < r[1])
list.add(new int[] { r[0], r[1] });
}
}
private int[] quickPos2(int low, int high) {
int p = random.nextInt(high - low);
if (p > 0)
swap(low, low + p);
int i = low;
int j = high;
int b = indexes[low];
long c = vals[b];
while (i < j) {
while (c <= vals[indexes[j]] && i < j)
j--;
while (c >= vals[indexes[i]] && i < j)
i++;
if (i < j)
swap(i, j);
}
indexes[low] = indexes[i];
indexes[i] = b;
return new int[] { low, j - 1, j + 1, high };
}
private void swap(int x, int y) {
int n = indexes[x];
indexes[x] = indexes[y];
indexes[y] = n;
}
}
static class ArrayIndexComparator implements Comparator<Integer> {
private final long[] array;
public ArrayIndexComparator(long[] array) {
this.array = array;
}
public Integer[] createIndexArray() {
Integer[] indexes = new Integer[array.length];
for (int i = 0; i < array.length; i++) {
indexes[i] = i;
}
return indexes;
}
@Override
public int compare(Integer index1, Integer index2) {
if (array[index1] < array[index2])
return -1;
if (array[index1] > array[index2])
return 1;
return 0;
}
}
/**
* TEST2: 1000000
* case0 cost 261ms
* case1 cost 182ms
* case2 cost 153ms
* case3 cost 203ms
* case4 cost 134ms
* case5 cost 106ms
* case6 cost 237ms
* case7 cost 183ms
* case8 cost 152ms
*/
static class MergeSort {
private long[] array; //原数组
private long[] arraySort; //排序数组
private long[] indexes; //数组下标
private int start; //排序开始位
private int end; //排序结束位
public MergeSort(long[] array) {
int size = array.length;
start = 0;
end = size - 1;
indexes = new long[size];
arraySort = Arrays.copyOf(array, array.length);
for (int i = 0; i < size; ++i) //初始时,下标是0...n的次序
indexes[i] = i;
}
public void sort() {
// System.out.println(JSON.toJSONString(arraySort));
this.sortRecursion(arraySort, indexes, start, end);
// System.out.println(JSON.toJSONString(arraySort));
// System.out.println(JSON.toJSONString(indexes));
}
private void sortRecursion(long[] arraySort, long[] indexes, int start, int end) {
if (start >= end)
return;
int middle = (end - start) / 2 + start;
sortRecursion(arraySort, indexes, start, middle);
sortRecursion(arraySort, indexes, middle + 1, end);
merge(arraySort, indexes, start, middle, end);
}
private void merge(long[] array, long[] indexes, int start, int middle, int end) {
int len1 = middle - start + 1;
int len2 = end - middle;
long leftArray[] = new long[len1];
long leftIndex[] = new long[len1];
long rightArray[] = new long[len2];
long rightIndex[] = new long[len2];
for (int i = 0; i < len1; ++i)
leftArray[i] = array[i + start];
for (int i = 0; i < len1; ++i)
leftIndex[i] = indexes[i + start];
for (int i = 0; i < len2; ++i)
rightArray[i] = array[i + middle + 1];
for (int i = 0; i < len2; ++i)
rightIndex[i] = indexes[i + middle + 1];
//merge
int i = 0, j = 0, k = start;
while (i < len1 && j < len2) {
if (leftArray[i] < rightArray[j]) {
array[k] = leftArray[i];
indexes[k] = leftIndex[i];
++i;
} else {
array[k] = rightArray[j];
indexes[k] = rightIndex[j];
++j;
}
++k;
}
while (i < len1) {
array[k] = leftArray[i];
indexes[k] = leftIndex[i];
++i;
++k;
}
while (j < len2) {
array[k] = rightArray[j];
indexes[k] = rightIndex[j];
++j;
++k;
}
}
}
}
java不同场景下的堆排序和归并排序实现
于 2023-01-16 17:41:20 首次发布
该代码示例展示了使用Java实现的不同排序算法(如堆排序、快速排序、归并排序)对不同数据分布的性能测试。每个测试用例都关注在特定数据规模下,保证在限定的时间内完成排序任务的能力。测试包括随机数、递增、递减、固定间隔等不同数据序列。
摘要由CSDN通过智能技术生成