Here you can find the source of median(double[] a)
Parameter | Description |
---|---|
a | a parameter |
public static double median(double[] a)
//package com.java2s; /**//from w ww .j ava2 s . com * * Copyright 2017 Florian Erhard * * 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. * */ import java.util.Arrays; import java.util.Comparator; public class Main { /** * Tuning parameter: list size at or below which insertion sort will be * used in preference to mergesort or quicksort. */ private static final int INSERTIONSORT_THRESHOLD = 7; /** * Computes the median of a. If a.length is an even number, the mean of the upper and lower median is taken. * Afterward, a will be sorted! * @param a * @return */ public static double median(double[] a) { Arrays.sort(a); if (a.length % 2 == 1) return a[a.length / 2]; else return (a[a.length / 2 - 1] + a[a.length / 2]) / 2.0; } /** * Sorts the specified array of objects into ascending order, according to * the {@linkplain Comparable natural ordering} * of its elements. All elements in the array * must implement the {@link Comparable} interface. Furthermore, all * elements in the array must be <i>mutually comparable</i> (that is, * <tt>e1.compareTo(e2)</tt> must not throw a <tt>ClassCastException</tt> * for any elements <tt>e1</tt> and <tt>e2</tt> in the array).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n*log(n) performance. * * @param a the array to be sorted * @throws ClassCastException if the array contains elements that are not * <i>mutually comparable</i> (for example, strings and integers). */ public static <T extends Comparable, S> void sort(T[] a, S[] a2) { if (a.length != a2.length) throw new IllegalArgumentException("Arrays don't have same length!"); T[] aux = (T[]) a.clone(); S[] aux2 = (S[]) a.clone(); mergeSort(aux, aux2, a, a2, 0, a.length, 0); } /** * Sorts the specified range of the specified array of objects into * ascending order, according to the * {@linkplain Comparable natural ordering} of its * elements. The range to be sorted extends from index * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive. * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.) All * elements in this range must implement the {@link Comparable} * interface. Furthermore, all elements in this range must be <i>mutually * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and * <tt>e2</tt> in the array).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n*log(n) performance. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be * sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or * <tt>toIndex > a.length</tt> * @throws ClassCastException if the array contains elements that are * not <i>mutually comparable</i> (for example, strings and * integers). */ public static <T extends Comparable, S> void sort(T[] a, S[] a2, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); rangeCheck(a2.length, fromIndex, toIndex); T[] aux = Arrays.copyOfRange(a, fromIndex, toIndex); S[] aux2 = Arrays.copyOfRange(a2, fromIndex, toIndex); mergeSort(aux, aux2, a, a2, fromIndex, toIndex, -fromIndex); } /** * Sorts the specified array of objects according to the order induced by * the specified comparator. All elements in the array must be * <i>mutually comparable</i> by the specified comparator (that is, * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt> * for any elements <tt>e1</tt> and <tt>e2</tt> in the array).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n*log(n) performance. * * @param a the array to be sorted * @param c the comparator to determine the order of the array. A * <tt>null</tt> value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @throws ClassCastException if the array contains elements that are * not <i>mutually comparable</i> using the specified comparator. */ public static <T, S> void sort(T[] a, S[] a2, Comparator<? super T> c) { T[] aux = (T[]) a.clone(); S[] aux2 = (S[]) a2.clone(); mergeSort(aux, aux2, a, a2, 0, a.length, 0, c); } /** * Sorts the specified range of the specified array of objects according * to the order induced by the specified comparator. The range to be * sorted extends from index <tt>fromIndex</tt>, inclusive, to index * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the * range to be sorted is empty.) All elements in the range must be * <i>mutually comparable</i> by the specified comparator (that is, * <tt>c.compare(e1, e2)</tt> must not throw a <tt>ClassCastException</tt> * for any elements <tt>e1</tt> and <tt>e2</tt> in the range).<p> * * This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort.<p> * * The sorting algorithm is a modified mergesort (in which the merge is * omitted if the highest element in the low sublist is less than the * lowest element in the high sublist). This algorithm offers guaranteed * n*log(n) performance. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be * sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param c the comparator to determine the order of the array. A * <tt>null</tt> value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @throws ClassCastException if the array contains elements that are not * <i>mutually comparable</i> using the specified comparator. * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or * <tt>toIndex > a.length</tt> */ public static <T, S> void sort(T[] a, S[] a2, int fromIndex, int toIndex, Comparator<? super T> c) { rangeCheck(a.length, fromIndex, toIndex); rangeCheck(a2.length, fromIndex, toIndex); T[] aux = (T[]) Arrays.copyOfRange(a, fromIndex, toIndex); S[] aux2 = (S[]) Arrays.copyOfRange(a2, fromIndex, toIndex); mergeSort(aux, aux2, a, a2, fromIndex, toIndex, -fromIndex, c); } /** * Src is the source array that starts at index 0 * Dest is the (possibly larger) array destination with a possible offset * low is the index in dest to start sorting * high is the end index in dest to end sorting * off is the offset to generate corresponding low, high in src */ private static <T extends Comparable, S> void mergeSort(T[] src, S[] src2, T[] dest, S[] dest2, int low, int high, int off) { int length = high - low; // Insertion sort on smallest arrays if (length < INSERTIONSORT_THRESHOLD) { for (int i = low; i < high; i++) for (int j = i; j > low && dest[j - 1].compareTo(dest[j]) > 0; j--) swap(dest, dest2, j, j - 1); return; } // Recursively sort halves of dest into src int destLow = low; int destHigh = high; low += off; high += off; int mid = (low + high) >>> 1; mergeSort(dest, dest2, src, src2, low, mid, -off); mergeSort(dest, dest2, src, src2, mid, high, -off); // If list is already sorted, just copy from src to dest. This is an // optimization that results in faster sorts for nearly ordered lists. if (src[mid - 1].compareTo(src[mid]) <= 0) { System.arraycopy(src, low, dest, destLow, length); System.arraycopy(src2, low, dest2, destLow, length); return; } // Merge sorted halves (now in src) into dest for (int i = destLow, p = low, q = mid; i < destHigh; i++) { if (q >= high || p < mid && src[p].compareTo(src[q]) <= 0) { dest2[i] = src2[p]; dest[i] = src[p++]; } else { dest2[i] = src2[q]; dest[i] = src[q++]; } } } /** * Src is the source array that starts at index 0 * Dest is the (possibly larger) array destination with a possible offset * low is the index in dest to start sorting * high is the end index in dest to end sorting * off is the offset into src corresponding to low in dest */ private static <T, S> void mergeSort(T[] src, S[] src2, T[] dest, S[] dest2, int low, int high, int off, Comparator c) { int length = high - low; // Insertion sort on smallest arrays if (length < INSERTIONSORT_THRESHOLD) { for (int i = low; i < high; i++) for (int j = i; j > low && c.compare(dest[j - 1], dest[j]) > 0; j--) swap(dest, dest2, j, j - 1); return; } // Recursively sort halves of dest into src int destLow = low; int destHigh = high; low += off; high += off; int mid = (low + high) >>> 1; mergeSort(dest, dest2, src, src2, low, mid, -off, c); mergeSort(dest, dest2, src, src2, mid, high, -off, c); // If list is already sorted, just copy from src to dest. This is an // optimization that results in faster sorts for nearly ordered lists. if (c.compare(src[mid - 1], src[mid]) <= 0) { System.arraycopy(src, low, dest, destLow, length); System.arraycopy(src2, low, dest2, destLow, length); return; } // Merge sorted halves (now in src) into dest for (int i = destLow, p = low, q = mid; i < destHigh; i++) { if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0) { dest2[i] = src2[p]; dest[i] = src[p++]; } else { dest2[i] = src2[q]; dest[i] = src[q++]; } } } /** * Check that fromIndex and toIndex are in range, and throw an * appropriate exception if they aren't. */ private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) { if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); if (fromIndex < 0) throw new ArrayIndexOutOfBoundsException(fromIndex); if (toIndex > arrayLen) throw new ArrayIndexOutOfBoundsException(toIndex); } public static <T> void swap(T[] a, int i, int j) { T temp = a[i]; a[i] = a[j]; a[j] = temp; } public static void swap(char[] a, int i, int j) { char temp = a[i]; a[i] = a[j]; a[j] = temp; } public static void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(long x[], T[] a2, int a, int b) { long t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(int x[], T[] a2, int a, int b) { int t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(int x[], double[] a2, int a, int b) { int t = x[a]; x[a] = x[b]; x[b] = t; double t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static void swap(int x[], int[] a2, int a, int b) { int t = x[a]; x[a] = x[b]; x[b] = t; int t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(short x[], T[] a2, int a, int b) { short t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(char x[], T[] a2, int a, int b) { char t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static void swap(char x[], char[] a2, int a, int b) { char t = x[a]; x[a] = x[b]; x[b] = t; char t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(byte x[], T[] a2, int a, int b) { byte t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(double x[], T[] a2, int a, int b) { double t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static void swap(double x[], int[] a2, int a, int b) { double t = x[a]; x[a] = x[b]; x[b] = t; int t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static void swap(double x[], double[] a2, int a, int b) { double t = x[a]; x[a] = x[b]; x[b] = t; double t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T> void swap(float x[], T[] a2, int a, int b) { float t = x[a]; x[a] = x[b]; x[b] = t; T t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T, S> void swap(T x[], S[] a2, int a, int b) { T t = x[a]; x[a] = x[b]; x[b] = t; S t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } /** * Swaps x[a] with x[b]. */ private static <T, S> void swap(T x[], int[] a2, int a, int b) { T t = x[a]; x[a] = x[b]; x[b] = t; int t2 = a2[a]; a2[a] = a2[b]; a2[b] = t2; } public static int compare(int[] a1, int[] a2) { int n = Math.min(a1.length, a2.length); for (int i = 0; i < n; i++) { int r = a1[i] - a2[i]; if (r != 0) return r; } return a1.length - a2.length; } public static int compare(char[] a1, char[] a2) { int n = Math.min(a1.length, a2.length); for (int i = 0; i < n; i++) { int r = a1[i] - a2[i]; if (r != 0) return r; } return a1.length - a2.length; } public static int compare(double[] a1, double[] a2, double eps) { int n = Math.min(a1.length, a2.length); for (int i = 0; i < n; i++) { double r = a1[i] - a2[i]; if (Math.abs(r) > eps) return (int) Math.signum(r); } return a1.length - a2.length; } }