Java Median median(double[] a)

Here you can find the source of median(double[] a)

Description

Computes the median of a.

License

Apache License

Parameter

Parameter Description
a a parameter

Declaration

public static double median(double[] a) 

Method Source Code

//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 &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; 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 &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; 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;
    }
}

Related

  1. median(ArrayList v)
  2. median(ArrayList values)
  3. Median(ArrayList values)
  4. median(double... a)
  5. median(double[] a)
  6. median(double[] arr)
  7. median(double[] array)
  8. median(double[] array)
  9. median(double[] data)