-Moved: Code generation is in its own sourceset. -Fixed: Bugs that caused that the project isnt buildable. -Changed: Made build.gradle to a standard.
1367 lines
60 KiB
Plaintext
1367 lines
60 KiB
Plaintext
package speiger.src.collections.PACKAGE.utils;
|
||
|
||
import java.util.Arrays;
|
||
import java.util.Random;
|
||
import java.util.concurrent.RecursiveAction;
|
||
#if !TYPE_OBJECT
|
||
|
||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||
#else
|
||
import java.util.Comparator;
|
||
|
||
#endif
|
||
import speiger.src.collections.utils.SanityChecks;
|
||
|
||
/**
|
||
* A Helper class for Arrays
|
||
*/
|
||
public class ARRAYS
|
||
{
|
||
public static final int BASE_THRESHOLD = 16;
|
||
public static final int PARALLEL_THRESHOLD = 8192;
|
||
|
||
#if !TYPE_OBJECT
|
||
public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0];
|
||
|
||
/**
|
||
* A Helper function to convert a Primitive Array to a CLASS_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @return a CLASS_TYPE Array of the input array.
|
||
*/
|
||
public static CLASS_TYPE[] wrap(KEY_TYPE[] a) {
|
||
return wrap(a, 0, a.length);
|
||
}
|
||
|
||
/**
|
||
* A Helper function to convert a Primitive Array to a CLASS_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @param length the maximum length that should be coverted
|
||
* @return a CLASS_TYPE Array of the input array.
|
||
*/
|
||
public static CLASS_TYPE[] wrap(KEY_TYPE[] a, int length) {
|
||
return wrap(a, 0, length);
|
||
}
|
||
|
||
/**
|
||
* A Helper function to convert a Primitive Array to a CLASS_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @param offset the starting offset of the inputarray
|
||
* @param length the maximum length that should be coverted
|
||
* @return a CLASS_TYPE Array of the input array.
|
||
*/
|
||
public static CLASS_TYPE[] wrap(KEY_TYPE[] a, int offset, int length) {
|
||
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
||
CLASS_TYPE[] result = new CLASS_TYPE[length];
|
||
for(int i = offset;i<length;i++)
|
||
result[i] = KEY_TO_OBJ(a[i]);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A Helper function to convert a CLASS_TYPE Array to a KEY_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @return a KEY_TYPE Array of the input array.
|
||
*/
|
||
public static KEY_TYPE[] unwrap(CLASS_TYPE[] a) {
|
||
return unwrap(a, 0, a.length);
|
||
}
|
||
|
||
/**
|
||
* A Helper function to convert a CLASS_TYPE Array to a KEY_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @param length the maximum length that should be coverted
|
||
* @return a KEY_TYPE Array of the input array.
|
||
*/
|
||
public static KEY_TYPE[] unwrap(CLASS_TYPE[] a, int length) {
|
||
return unwrap(a, 0, length);
|
||
}
|
||
|
||
/**
|
||
* A Helper function to convert a CLASS_TYPE Array to a KEY_TYPE Array.
|
||
* @param a the array that should be converted
|
||
* @param offset the starting offset of the inputarray
|
||
* @param length the maximum length that should be coverted
|
||
* @return a KEY_TYPE Array of the input array.
|
||
*/
|
||
public static KEY_TYPE[] unwrap(CLASS_TYPE[] a, int offset, int length) {
|
||
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
||
KEY_TYPE[] result = new KEY_TYPE[length];
|
||
for(int i = offset;i<length;i++)
|
||
result[i] = OBJ_TO_KEY(a[i]);
|
||
return result;
|
||
}
|
||
|
||
#else
|
||
public static final Object[] EMPTY_ARRAY = new Object[0];
|
||
|
||
/**
|
||
* Function to create a new Array of a given size
|
||
* @param clz the class type of array that is requested
|
||
* @param length the lenght the array should be.
|
||
* @return a Array with the requested type and length
|
||
*/
|
||
public static GENERIC_KEY_BRACES KEY_TYPE[] newArray(Class<KEY_TYPE> clz, int length) {
|
||
if(clz == Object.class) return (KEY_TYPE[])new Object[length];
|
||
return (KEY_TYPE[]) java.lang.reflect.Array.newInstance(clz, length);
|
||
}
|
||
|
||
#endif
|
||
public static GENERIC_KEY_BRACES int shiftDown(KEY_TYPE[] data, int size, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
||
int half = size >>> 1;
|
||
KEY_TYPE value = data[index];
|
||
if(comp != null) {
|
||
while(index < half) {
|
||
int child = (index << 1) + 1;
|
||
KEY_TYPE childValue = data[child];
|
||
int right = child+1;
|
||
if(right < size && comp.compare(data[right], childValue) < 0) childValue = data[child = right];
|
||
if(comp.compare(value, childValue) <= 0) break;
|
||
data[index] = childValue;
|
||
index = child;
|
||
}
|
||
}
|
||
else {
|
||
while(index < half) {
|
||
int child = (index << 1) + 1;
|
||
KEY_TYPE childValue = data[child];
|
||
int right = child+1;
|
||
if(right < size && COMPAREABLE_TO_KEY(data[right], childValue) < 0) childValue = data[child = right];
|
||
if(COMPAREABLE_TO_KEY(value, childValue) <= 0) break;
|
||
data[index] = childValue;
|
||
index = child;
|
||
}
|
||
}
|
||
data[index] = value;
|
||
return index;
|
||
}
|
||
|
||
public static GENERIC_KEY_BRACES int shiftUp(KEY_TYPE[] data, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
||
KEY_TYPE value = data[index];
|
||
if(comp != null) {
|
||
while(index > 0) {
|
||
int parent = (index - 1) >>> 1;
|
||
KEY_TYPE parentValue = data[parent];
|
||
if(comp.compare(value, parentValue) >= 0) break;
|
||
data[index] = parentValue;
|
||
index = parent;
|
||
}
|
||
}
|
||
else {
|
||
while(index > 0) {
|
||
int parent = (index - 1) >>> 1;
|
||
KEY_TYPE parentValue = data[parent];
|
||
if(COMPAREABLE_TO_KEY(value, parentValue) >= 0) break;
|
||
data[index] = parentValue;
|
||
index = parent;
|
||
}
|
||
}
|
||
data[index] = value;
|
||
return index;
|
||
}
|
||
|
||
public static GENERIC_KEY_BRACES KEY_TYPE[] heapify(KEY_TYPE[] data, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
||
for(int i = (size >>> 1) - 1;i>=0;shiftDown(data, size, i--, comp));
|
||
return data;
|
||
}
|
||
|
||
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array) {
|
||
return shuffle(array, SanityChecks.getRandom());
|
||
}
|
||
|
||
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, Random random) {
|
||
for(int i = array.length-1; i>=0;i--) {
|
||
int p = random.nextInt(i + 1);
|
||
KEY_TYPE t = array[i];
|
||
array[i] = array[p];
|
||
array[p] = t;
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
stableSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
stableSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
mergeSort(array, null, from, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void stableSort(KEY_TYPE[] array) {
|
||
stableSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void stableSort(KEY_TYPE[] array, int length) {
|
||
stableSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Stable sort referres to Mergesort or Insertionsort
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void stableSort(KEY_TYPE[] array, int from, int to) {
|
||
mergeSort(array, null, from, to);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
unstableSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
unstableSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
quickSort(array, from, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void unstableSort(KEY_TYPE[] array) {
|
||
unstableSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void unstableSort(KEY_TYPE[] array, int length) {
|
||
unstableSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order,
|
||
* potentially dynamically choosing an appropriate algorithm given the type and size of the array.
|
||
* Unstable sort referres to QuickSort or SelectionSort
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void unstableSort(KEY_TYPE[] array, int from, int to) {
|
||
quickSort(array, from, to);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
insertionSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
insertionSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
for (int i = from+1;i<to; i++) {
|
||
KEY_TYPE current = array[i];
|
||
int j = i - 1;
|
||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||
array[j+1] = array[j--];
|
||
}
|
||
array[j+1] = current;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void insertionSort(KEY_TYPE[] array) {
|
||
insertionSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void insertionSort(KEY_TYPE[] array, int length) {
|
||
insertionSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void insertionSort(KEY_TYPE[] array, int from, int to) {
|
||
for (int i = from+1;i<to; i++) {
|
||
KEY_TYPE current = array[i];
|
||
int j = i - 1;
|
||
while(j >= from && COMPAREABLE_TO_KEY(current, array[j]) < 0) {
|
||
array[j+1] = array[j--];
|
||
}
|
||
array[j+1] = current;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
selectionSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
selectionSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
for (int i = from; i < to; i++) {
|
||
KEY_TYPE min = array[i];
|
||
int minId = i;
|
||
for(int j = i+1; j < to; j++) {
|
||
if(comp.compare(array[j], min) < 0) {
|
||
min = array[j];
|
||
minId = j;
|
||
}
|
||
}
|
||
KEY_TYPE temp = array[i];
|
||
array[i] = min;
|
||
array[minId] = temp;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void selectionSort(KEY_TYPE[] array) {
|
||
selectionSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void selectionSort(KEY_TYPE[] array, int length) {
|
||
selectionSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to) {
|
||
for (int i = from; i < to; i++) {
|
||
KEY_TYPE min = array[i];
|
||
int minId = i;
|
||
for(int j = i+1; j < to; j++) {
|
||
if(COMPAREABLE_TO_KEY(array[j], min) < 0) {
|
||
min = array[j];
|
||
minId = j;
|
||
}
|
||
}
|
||
KEY_TYPE temp = array[i];
|
||
array[i] = min;
|
||
array[minId] = temp;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
mergeSort(array, null, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
mergeSort(array, null, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||
int mid = (from + to) >>> 1;
|
||
mergeSort(supp, array, from, mid, comp);
|
||
mergeSort(supp, array, mid, to, comp);
|
||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||
{
|
||
System.arraycopy(supp, from, array, from, to - from);
|
||
return;
|
||
}
|
||
for(int p = from, q = mid;from < to;from++) {
|
||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||
else array[from] = supp[q++];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void mergeSort(KEY_TYPE[] array) {
|
||
mergeSort(array, null, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void mergeSort(KEY_TYPE[] array, int length) {
|
||
mergeSort(array, null, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to);
|
||
return;
|
||
}
|
||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||
int mid = (from + to) >>> 1;
|
||
mergeSort(supp, array, from, mid);
|
||
mergeSort(supp, array, mid, to);
|
||
if(COMPAREABLE_TO_KEY(supp[mid - 1], supp[mid]) <= 0)
|
||
{
|
||
System.arraycopy(supp, from, array, from, to - from);
|
||
return;
|
||
}
|
||
for(int p = from, q = mid;from < to;from++) {
|
||
if(q >= to || p < mid && COMPAREABLE_TO_KEY(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||
else array[from] = supp[q++];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelMergeSort(array, null, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelMergeSort(array, null, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new MergeSortActionCompBRACES(array, supp, from, to, comp));
|
||
return;
|
||
}
|
||
mergeSort(array, supp, from, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array) {
|
||
parallelMergeSort(array, null, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, int length) {
|
||
parallelMergeSort(array, null, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new MergeSortActionBRACES(array, supp, from, to));
|
||
return;
|
||
}
|
||
mergeSort(array, supp, from, to);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
memFreeMergeSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
memFreeMergeSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
int mid = (from + to) >>> 1;
|
||
memFreeMergeSort(array, from, mid, comp);
|
||
memFreeMergeSort(array, mid, to, comp);
|
||
if(comp.compare(array[mid - 1], array[mid]) <= 0)
|
||
return;
|
||
for(int i = from, j = mid, compare;i < j && j < to;) {
|
||
if((compare = comp.compare(array[i], array[j])) < 0)
|
||
i++;
|
||
else if(compare == 0) swap(array, ++i, j);
|
||
else {
|
||
int k = j;
|
||
for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++);
|
||
if(j == k) {
|
||
swap(array, i++, j);
|
||
continue;
|
||
}
|
||
else if(j + 1 == k) {
|
||
KEY_TYPE value = array[j];
|
||
System.arraycopy(array, i, array, i+1, j - i);
|
||
array[i] = value;
|
||
i++;
|
||
j++;
|
||
continue;
|
||
}
|
||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||
System.arraycopy(array, j, data, 0, data.length);
|
||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||
System.arraycopy(data, 0, array, i, data.length);
|
||
i+=data.length;
|
||
j+=data.length;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array) {
|
||
memFreeMergeSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length) {
|
||
memFreeMergeSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to) {
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to);
|
||
return;
|
||
}
|
||
int mid = (from + to) >>> 1;
|
||
memFreeMergeSort(array, from, mid);
|
||
memFreeMergeSort(array, mid, to);
|
||
if(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0)
|
||
return;
|
||
for(int i = from, j = mid, comp;i < j && j < to;) {
|
||
if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0)
|
||
i++;
|
||
else if(comp == 0) swap(array, ++i, j);
|
||
else {
|
||
int k = j;
|
||
for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++);
|
||
if(j == k) {
|
||
swap(array, i++, j);
|
||
continue;
|
||
}
|
||
else if(j + 1 == k) {
|
||
KEY_TYPE value = array[j];
|
||
System.arraycopy(array, i, array, i+1, j - i);
|
||
array[i] = value;
|
||
i++;
|
||
j++;
|
||
continue;
|
||
}
|
||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||
System.arraycopy(array, j, data, 0, data.length);
|
||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||
System.arraycopy(data, 0, array, i, data.length);
|
||
i+=data.length;
|
||
j+=data.length;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelMemFreeMergeSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelMemFreeMergeSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new MemFreeMergeSortActionCompBRACES(array, from, to, comp));
|
||
return;
|
||
}
|
||
memFreeMergeSort(array, from, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array) {
|
||
parallelMemFreeMergeSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length) {
|
||
parallelMemFreeMergeSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||
* @author Speiger
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int from, int to) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new MemFreeMergeSortActionBRACES(array, from, to));
|
||
return;
|
||
}
|
||
memFreeMergeSort(array, from, to);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
quickSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
quickSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
*/
|
||
public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
int length = to - from;
|
||
if(length <= 0) return;
|
||
if(length < BASE_THRESHOLD) {
|
||
selectionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||
int a = from, b = a, c = to - 1, d = c;
|
||
for(int compare;;swap(array, b++, c--)) {
|
||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||
if(compare == 0) swap(array, a++, b);
|
||
}
|
||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||
if(compare == 0) swap(array, c, d--);
|
||
}
|
||
if(b>c) break;
|
||
}
|
||
swap(array, from, b, Math.min(a - from, b - a));
|
||
swap(array, b, to, Math.min(d - c, to - d - 1));
|
||
if((length = b - a) > 1) quickSort(array, from, from + length, comp);
|
||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void quickSort(KEY_TYPE[] array) {
|
||
quickSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void quickSort(KEY_TYPE[] array, int length) {
|
||
quickSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void quickSort(KEY_TYPE[] array, int from, int to) {
|
||
int length = to - from;
|
||
if(length <= 0) return;
|
||
if(length < BASE_THRESHOLD) {
|
||
selectionSort(array, from, to);
|
||
return;
|
||
}
|
||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)];
|
||
int a = from, b = a, c = to - 1, d = c;
|
||
for(int comp = 0;;swap(array, b++, c--)) {
|
||
for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) {
|
||
if(comp == 0) swap(array, a++, b);
|
||
}
|
||
for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) {
|
||
if(comp == 0) swap(array, c, d--);
|
||
}
|
||
if(b>c) break;
|
||
}
|
||
swap(array, from, b, Math.min(a - from, b - a));
|
||
swap(array, b, to, Math.min(d - c, to - d - 1));
|
||
if((length = b - a) > 1) quickSort(array, from, from + length);
|
||
if((length = d - c) > 1) quickSort(array, to - length, to);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelQuickSort(array, 0, array.length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
parallelQuickSort(array, 0, length, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @param comp the Comparator that decides the sorting order
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new QuickSortActionCompBRACES(array, from, to, comp));
|
||
return;
|
||
}
|
||
quickSort(array, from, to, comp);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array) {
|
||
parallelQuickSort(array, 0, array.length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param length the maxmium size of the array to be sorted
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int length) {
|
||
parallelQuickSort(array, 0, length);
|
||
}
|
||
|
||
/**
|
||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, “Engineering a Sort Function”, Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||
* @param array the array that needs to be sorted
|
||
* @param from where the array should be sorted from
|
||
* @param to where the array should be sorted to
|
||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||
*/
|
||
public static COMPAREABLE_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int from, int to) {
|
||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||
SanityChecks.invokeTask(new QuickSortActionBRACES(array, from, to));
|
||
return;
|
||
}
|
||
quickSort(array, from, to);
|
||
}
|
||
|
||
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to) {
|
||
KEY_TYPE t = a[from];
|
||
a[from] = a[to];
|
||
a[to] = t;
|
||
}
|
||
|
||
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, int length) {
|
||
to -= length;
|
||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||
}
|
||
|
||
static GENERIC_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||
}
|
||
|
||
static GENERIC_KEY_BRACES int medium(KEY_TYPE[] data, int a, int b, int c, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||
return comp.compare(data[a], data[b]) < 0 ? (comp.compare(data[b], data[c]) < 0 ? b : comp.compare(data[a], data[c]) < 0 ? c : a) : (comp.compare(data[b], data[c]) > 0 ? b : comp.compare(data[a], data[c]) > 0 ? c : a);
|
||
}
|
||
|
||
static COMPAREABLE_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length) {
|
||
return medium(data, medium(data, a, a + length, a + (length * 2)), medium(data, b - length, b, b + length), medium(data, c - (length * 2), c - length, c));
|
||
}
|
||
|
||
static COMPAREABLE_KEY_BRACES int medium(KEY_TYPE[] data, int a, int b, int c) {
|
||
return COMPAREABLE_TO_KEY(data[a], data[b]) < 0 ? (COMPAREABLE_TO_KEY(data[b], data[c]) < 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) < 0 ? c : a) : (COMPAREABLE_TO_KEY(data[b], data[c]) > 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) > 0 ? c : a);
|
||
}
|
||
|
||
static class QuickSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
int from;
|
||
int to;
|
||
|
||
QuickSortAction(KEY_TYPE[] array, int from, int to)
|
||
{
|
||
this.array = array;
|
||
this.from = from;
|
||
this.to = to;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
int length = to - from;
|
||
if(length <= 0) return;
|
||
if(length < BASE_THRESHOLD) {
|
||
selectionSort(array, from, to);
|
||
return;
|
||
}
|
||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)];
|
||
int a = from, b = a, c = to - 1, d = c;
|
||
for(int comp = 0;;swap(array, b++, c--)) {
|
||
for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) {
|
||
if(comp == 0) swap(array, a++, b);
|
||
}
|
||
for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) {
|
||
if(comp == 0) swap(array, c, d--);
|
||
}
|
||
if(b>c) break;
|
||
}
|
||
swap(array, from, b, Math.min(a - from, b - a));
|
||
swap(array, b, to, Math.min(d - c, to - d - 1));
|
||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionBRACES(array, from, from + (b - a)), new QuickSortActionBRACES(array, to - (d - c), to));
|
||
else if(b - a > 1) new QuickSortActionBRACES(array, from, from + (b - a)).invoke();
|
||
else if(d - c > 1) new QuickSortActionBRACES(array, to - (d - c), to).invoke();
|
||
}
|
||
}
|
||
|
||
static class QuickSortActionComp KEY_GENERIC_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
int from;
|
||
int to;
|
||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||
|
||
QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||
{
|
||
this.array = array;
|
||
this.from = from;
|
||
this.to = to;
|
||
this.comp = comp;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
int length = to - from;
|
||
if(length <= 0) return;
|
||
if(length < BASE_THRESHOLD) {
|
||
selectionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||
int a = from, b = a, c = to - 1, d = c;
|
||
for(int compare;;swap(array, b++, c--)) {
|
||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||
if(compare == 0) swap(array, a++, b);
|
||
}
|
||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||
if(compare == 0) swap(array, c, d--);
|
||
}
|
||
if(b>c) break;
|
||
}
|
||
swap(array, from, b, Math.min(a - from, b - a));
|
||
swap(array, b, to, Math.min(d - c, to - d - 1));
|
||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompBRACES(array, from, from + (b - a), comp), new QuickSortActionCompBRACES(array, to - (d - c), to, comp));
|
||
else if(b - a > 1) new QuickSortActionCompBRACES(array, from, from + (b - a), comp).invoke();
|
||
else if(d - c > 1) new QuickSortActionCompBRACES(array, to - (d - c), to, comp).invoke();
|
||
}
|
||
}
|
||
|
||
static class MergeSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
KEY_TYPE[] supp;
|
||
int from;
|
||
int to;
|
||
|
||
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to)
|
||
{
|
||
this.array = array;
|
||
this.supp = supp;
|
||
this.from = from;
|
||
this.to = to;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to);
|
||
return;
|
||
}
|
||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||
int mid = (from + to) >>> 1;
|
||
invokeAll(new MergeSortActionBRACES(supp, array, from, mid), new MergeSortActionBRACES(supp, array, mid, to));
|
||
if(COMPAREABLE_TO_KEY(supp[mid - 1], supp[mid]) <= 0)
|
||
{
|
||
System.arraycopy(supp, from, array, from, to - from);
|
||
return;
|
||
}
|
||
for(int p = from, q = mid;from < to;from++) {
|
||
if(q >= to || p < mid && COMPAREABLE_TO_KEY(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||
else array[from] = supp[q++];
|
||
}
|
||
}
|
||
}
|
||
|
||
static class MergeSortActionComp KEY_GENERIC_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
KEY_TYPE[] supp;
|
||
int from;
|
||
int to;
|
||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||
|
||
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||
{
|
||
this.array = array;
|
||
this.supp = supp;
|
||
this.from = from;
|
||
this.to = to;
|
||
this.comp = comp;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||
int mid = (from + to) >>> 1;
|
||
invokeAll(new MergeSortActionCompBRACES(supp, array, from, mid, comp), new MergeSortActionCompBRACES(supp, array, mid, to, comp));
|
||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||
{
|
||
System.arraycopy(supp, from, array, from, to - from);
|
||
return;
|
||
}
|
||
for(int p = from, q = mid;from < to;from++) {
|
||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||
else array[from] = supp[q++];
|
||
}
|
||
}
|
||
}
|
||
|
||
static class MemFreeMergeSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
int from;
|
||
int to;
|
||
|
||
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to)
|
||
{
|
||
this.array = array;
|
||
this.from = from;
|
||
this.to = to;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to);
|
||
return;
|
||
}
|
||
int mid = (from + to) >>> 1;
|
||
invokeAll(new MemFreeMergeSortActionBRACES(array, from, mid), new MemFreeMergeSortActionBRACES(array, mid, to));
|
||
if(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0)
|
||
return;
|
||
for(int i = from, j = mid, comp;i < j && j < to;) {
|
||
if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0)
|
||
i++;
|
||
else if(comp == 0) swap(array, ++i, j);
|
||
else {
|
||
int k = j;
|
||
for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++);
|
||
if(j == k) {
|
||
swap(array, i++, j);
|
||
continue;
|
||
}
|
||
else if(j + 1 == k) {
|
||
KEY_TYPE value = array[j];
|
||
System.arraycopy(array, i, array, i+1, j - i);
|
||
array[i] = value;
|
||
i++;
|
||
j++;
|
||
continue;
|
||
}
|
||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||
System.arraycopy(array, j, data, 0, data.length);
|
||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||
System.arraycopy(data, 0, array, i, data.length);
|
||
i+=data.length;
|
||
j+=data.length;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static class MemFreeMergeSortActionComp KEY_GENERIC_TYPE extends RecursiveAction {
|
||
private static final long serialVersionUID = 0L;
|
||
KEY_TYPE[] array;
|
||
int from;
|
||
int to;
|
||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||
|
||
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||
{
|
||
this.array = array;
|
||
this.from = from;
|
||
this.to = to;
|
||
this.comp = comp;
|
||
}
|
||
|
||
@Override
|
||
protected void compute()
|
||
{
|
||
if(to - from < BASE_THRESHOLD) {
|
||
insertionSort(array, from, to, comp);
|
||
return;
|
||
}
|
||
int mid = (from + to) >>> 1;
|
||
invokeAll(new MemFreeMergeSortActionCompBRACES(array, from, mid, comp), new MemFreeMergeSortActionCompBRACES(array, mid, to, comp));
|
||
|
||
if(comp.compare(array[mid - 1], array[mid]) <= 0)
|
||
return;
|
||
for(int i = from, j = mid, compare;i < j && j < to;) {
|
||
if((compare = comp.compare(array[i], array[j])) < 0)
|
||
i++;
|
||
else if(compare == 0) swap(array, ++i, j);
|
||
else {
|
||
int k = j;
|
||
for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++);
|
||
if(j == k) {
|
||
swap(array, i++, j);
|
||
continue;
|
||
}
|
||
else if(j + 1 == k) {
|
||
KEY_TYPE value = array[j];
|
||
System.arraycopy(array, i, array, i+1, j - i);
|
||
array[i] = value;
|
||
i++;
|
||
j++;
|
||
continue;
|
||
}
|
||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||
System.arraycopy(array, j, data, 0, data.length);
|
||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||
System.arraycopy(data, 0, array, i, data.length);
|
||
i+=data.length;
|
||
j+=data.length;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |