/*
 * Copyright (c) 2018 Goldman Sachs.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 */

package org.eclipse.collections.impl.utility.primitive;

import org.eclipse.collections.api.block.comparator.primitive.IntComparator;

IntQuickSort is an implementation of the Quick Sort algorithm as described in Donald Knuth's TAOCP with some optimizations. It supports indirect array sorting based on primitive comparators and/or key values extracted from the array values if a sort order other thant the natural one of the array elements is required. This file was automatically generated from template file primitiveSort.stg.
/** * IntQuickSort is an implementation of the Quick Sort algorithm as described in Donald Knuth's TAOCP with some * optimizations. It supports indirect array sorting based on primitive comparators and/or key values extracted from * the array values if a sort order other thant the natural one of the array elements is required. * * This file was automatically generated from template file primitiveSort.stg. * */
public final class IntQuickSort { private static final int SORT_SMALL_SIZE = 9; private IntQuickSort() { } public static void sort(int[] array, int left, int right, IntComparator comparator) { int size = right - left + 1; if (size <= IntQuickSort.SORT_SMALL_SIZE) { IntQuickSort.insertionSort(array, left, right, comparator); } else { // Initialize new stage int mid = (right - (right / 2)) + (left / 2); int leftVal = array[left]; int rightVal = array[right]; int midVal = array[mid]; int swapIndex = -1; if (comparator.compare(leftVal, midVal) > 0 && comparator.compare(leftVal, rightVal) > 0) { swapIndex = (comparator.compare(midVal, rightVal) < 0) ? right : mid; } else if (comparator.compare(leftVal, midVal) < 0 && comparator.compare(leftVal, rightVal) < 0) { swapIndex = (comparator.compare(midVal, rightVal) < 0) ? mid : right; } if (swapIndex > 0) { swap(array, left, swapIndex); } int pivot = array[left]; int i = left + 1; int j = right; while (i < j) { // Compare: Key(i) : Key, skip all which are <= pivot or until hit j while (comparator.compare(array[i], pivot) <= 0 && i < j) { i++; } // Compare Key : Key(j), skip all which are > pivot or until hit i while (comparator.compare(pivot, array[j]) < 0 && j > i - 1) { j--; } if (i < j) { swap(array, i, j); } else { swap(array, left, j); } } // Sort partitions, skipping sequences of elements equal to the pivot if (right > j + 1) { int from = j + 1; while (right > from && comparator.compare(pivot, array[from]) == 0) { from++; } if (right > from) { IntQuickSort.sort(array, from, right, comparator); } } if (left < j - 1) { int to = j - 1; while (to > left && comparator.compare(pivot, array[to]) == 0) { to--; } if (left < to) { IntQuickSort.sort(array, left, to, comparator); } } } } private static void insertionSort(int[] array, int left, int right, IntComparator comparator) { for (int j = left + 1; j <= right; j++) { if (comparator.compare(array[j - 1], array[j]) > 0) { int key = array[j]; int i = j - 1; do { array[i + 1] = array[i]; i--; } while (i > -1 && comparator.compare(key, array[i]) < 0); array[i + 1] = key; } } } private static void swap(int[] array, int i1, int i2) { int value = array[i1]; array[i1] = array[i2]; array[i2] = value; } }