All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javaemul.internal.MergeSorter Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2023 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package javaemul.internal;

import java.util.Comparator;

final class MergeSorter {
  /**
   * Performs a merge sort on the specified portion of an object array.
   *
   * 

Uses O(n) temporary space to perform the merge, but is stable. */ public static void sort(T[] x, int fromIndex, int toIndex, Comparator comp) { T[] temp = (T[]) ArrayHelper.unsafeClone(x, fromIndex, toIndex); mergeSort(temp, x, fromIndex, toIndex, -fromIndex, comp); } /** * Recursive helper function for {@link #sort(T[], int, int, Comparator)}. * * @param temp temporary space, as large as the range of elements being sorted. On entry, temp * should contain a copy of the sort range from array. * @param array array to sort * @param low lower bound of range to sort * @param high upper bound of range to sort * @param ofs offset to convert an array index into a temp index * @param comp comparison function */ private static void mergeSort( T[] temp, T[] array, int low, int high, int ofs, Comparator comp) { int length = high - low; // insertion sort for small arrays if (length < 7) { insertionSort(array, low, high, comp); return; } // recursively sort both halves, using the array as temp space int tempLow = low + ofs; int tempHigh = high + ofs; int tempMid = tempLow + ((tempHigh - tempLow) >> 1); mergeSort(array, temp, tempLow, tempMid, -ofs, comp); mergeSort(array, temp, tempMid, tempHigh, -ofs, comp); // Skip merge if already in order - just copy from temp if (comp.compare(temp[tempMid - 1], temp[tempMid]) <= 0) { // TODO(jat): use System.arraycopy when that is implemented and more // efficient than this while (low < high) { array[low++] = temp[tempLow++]; } return; } // merge sorted halves merge(temp, tempLow, tempMid, tempHigh, array, low, high, comp); } /** * Sort a small subsection of an array by insertion sort. * * @param array array to sort * @param low lower bound of range to sort * @param high upper bound of range to sort * @param comp comparator to use */ private static void insertionSort(T[] array, int low, int high, Comparator comp) { for (int i = low + 1; i < high; ++i) { for (int j = i; j > low && comp.compare(array[j - 1], array[j]) > 0; --j) { T t = array[j]; array[j] = array[j - 1]; array[j - 1] = t; } } } /** * Merge the two sorted subarrays (srcLow,srcMid] and (srcMid,srcHigh] into dest. * * @param src source array for merge * @param srcLow lower bound of bottom sorted half * @param srcMid upper bound of bottom sorted half & lower bound of top sorted half * @param srcHigh upper bound of top sorted half * @param dest destination array for merge * @param destLow lower bound of destination * @param destHigh upper bound of destination * @param comp comparator to use */ private static void merge( T[] src, int srcLow, int srcMid, int srcHigh, T[] dest, int destLow, int destHigh, Comparator comp) { // can't destroy srcMid because we need it as a bound on the lower half int topIdx = srcMid; while (destLow < destHigh) { if (topIdx >= srcHigh || (srcLow < srcMid && comp.compare(src[srcLow], src[topIdx]) <= 0)) { dest[destLow++] = src[srcLow++]; } else { dest[destLow++] = src[topIdx++]; } } } private MergeSorter() {} }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy