Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template

1596 lines
67 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.utils.SanityChecks;
/**
* A Helper class for Arrays
*/
public class ARRAYS
{
/** Default Limit for Insertion/Selection Sort */
public static final int BASE_THRESHOLD = 16;
/** Default Threshold for Multithreaded Sorting Algorythm options*/
public static final int PARALLEL_THRESHOLD = 8192;
#if !TYPE_OBJECT
/** Empty Array Reference used for Uninitialized Collections */
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
/** Empty Array Reference used for Uninitialized Collections */
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.
* @ArrayType(T)
* @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
/**
* A Helper function that pours all elements of a iterator into a Array
* @param iter the elements that should be gathered.
* @ArrayType(T)
* @return array with all elements of the iterator
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter) {
return pour(iter, Integer.MAX_VALUE);
}
/**
* A Helper function that pours all elements of a iterator into a Array
* @param iter the elements that should be gathered.
* @param max how many elements should be added
* @ArrayType(T)
* @return array with all requested elements of the iterator
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) {
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
ITERATORS.pour(iter, list, max);
return list.TO_ARRAY(NEW_KEY_ARRAY(list.size()));
}
/**
* Method to validate if the current value is the lowest value in the heap
* @param data the current heap.
* @param size the size of the heap
* @param index the index that should be validated
* @param comp the comparator to sort the heap. Can be null
* @ArrayType(T)
* @return the index the element was shifted to
*/
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;
}
/**
* Method to sort a specific value into the heap.
* @param data the heap itself.
* @param index that should be heapified.
* @param comp the comparator to sort the heap. Can be null
* @ArrayType(T)
* @return the index the element was shifted to
*/
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;
}
/**
* Helper function to create a Heap out of an array.
* @param data the array to heapify
* @param size the current size of elements within the array.
* @param comp the Comparator to sort the array. Can be null
* @ArrayType(T)
* @return the input array
*/
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;
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @ArrayType(T)
* @note This uses the SanityChecks#getRandom
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array) {
return shuffle(array, SanityChecks.getRandom());
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @param length the length of the array
* @ArrayType(T)
* @note This uses the SanityChecks#getRandom
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length) {
return shuffle(array, 0, length, SanityChecks.getRandom());
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @param offset the start array
* @param length the length of the array
* @ArrayType(T)
* @note This uses the SanityChecks#getRandom
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length) {
return shuffle(array, offset, length, SanityChecks.getRandom());
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @param random the Random Number Generator that should be used for the shuffling
* @ArrayType(T)
* @return the provided sorted array
*/
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;
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @param length the length of the array
* @param random the Random Number Generator that should be used for the shuffling
* @ArrayType(T)
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, Random random) {
return shuffle(array, 0, length, random);
}
/**
* Simple Shuffle method for Arrays.
* @param array the elements that should be shuffled
* @param offset the start array
* @param length the length of the array
* @param random the Random Number Generator that should be used for the shuffling
* @ArrayType(T)
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, Random random) {
for(int i = length-1; i>=0;i--) {
int p = offset + random.nextInt(i + 1);
KEY_TYPE t = array[offset+i];
array[offset+i] = array[p];
array[p] = t;
}
return array;
}
/**
* Simple Array Reversal method
* @param array the Array that should flip
* @ArrayType(T)
* @return the provided array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array) {
return reverse(array, 0, array.length);
}
/**
* Simple Array Reversal method
* @param array the Array that should flip
* @param length the length of the array
* @ArrayType(T)
* @return the provided array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int length) {
return reverse(array, 0, length);
}
/**
* Simple Array Reversal method
* @param array the Array that should flip
* @param length the length of the array
* @param offset the start of the array
* @ArrayType(T)
* @return the provided array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int offset, int length) {
for (int i = offset, mid = offset + length >> 1, j = offset + length - 1; i < mid; i++, j--) {
KEY_TYPE temp = array[i];
array[i] = array[j];
array[j] = temp;
}
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
* @ArrayType(T)
* @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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @param to where the array should be sorted to
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @param to where the array should be sorted to
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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 supp the auxillary array that is used to simplify the sorting
* @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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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 supp the auxillary array that is used to simplify the sorting
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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 supp the auxillary array that is used to simplify the sorting
* @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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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 supp the auxillary array that is used to simplify the sorting
* @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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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
* @ArrayType(T)
*/
public static GENERIC_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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @ArrayType(T)
*/
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), pages12491265, 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
* @ArrayType(T)
*/
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), pages12491265, 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
* @ArrayType(T)
*/
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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @ArrayType(T)
*/
public static GENERIC_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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @ArrayType(T)
*/
public static GENERIC_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), pages12491265, 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
* @ArrayType(T)
*/
public static GENERIC_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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @ArrayType(T)
* @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), pages12491265, 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
* @ArrayType(T)
* @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), pages12491265, 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
* @ArrayType(T)
* @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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @ArrayType(T)
* @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) {
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), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @ArrayType(T)
* @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) {
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), pages12491265, 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
* @ArrayType(T)
* @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) {
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 GENERIC_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 GENERIC_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_GENERIC_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_GENERIC_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_GENERIC_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;
}
}
}
}
}