Compute the median of an array efficiently using the QuickSelect method.

Note: the array is <b>modified</b> by this.

@param <T> object type
@param data Data to process
@param comparator Comparator to use
@return Median value
507091
public static <T> T median(List<? extends T> data, Comparator<? super T> comparator) {
    return median(data, comparator, 0, data.size());
  }
261972
def median_low(data):
    
    data = sorted(data)
    n = len(data)
    if n == 0:
        raise StatisticsError("no median for empty data")
    if n % 2 == 1:
        return data[n // 2]
    else:
        return data[n // 2 - 1]
104543
private static <T> void insertionSort(List<T> data, Comparator<? super T> comparator, int start, int end) {
    for(int i = start + 1; i < end; i++) {
      for(int j = i; j > start && comparator.compare(data.get(j - 1), data.get(j)) > 0; j--) {
        swap(data, j, j - 1);
      }
    }
  }
967744
public static <T> ArrayList<T> sortThis(ArrayList<T> list, Comparator<? super T> comparator)
    {
        int size = list.size();
        if (ArrayListIterate.canAccessInternalArray(list))
        {
            Arrays.sort(ArrayListIterate.getInternalArray(list), 0, size, comparator);
        }
        else
        {
            Collections.sort(list, comparator);
        }
        return list;
    }
606109
private void sort(final T[] array, int start, int end, Comparator<T> lt) {
    if (start == end)
      return;
    if ((end - start) <= 15)
      this.selectionSort(array, start, end, lt);
    else {
      final T pivot = array[start + ((end - start) / 2)];
      T tmp;
      int i = start - 1;
      int j = end;
      while (true) {
        do
          i++;
        while (lt.compare(array[i], pivot) < 0);
        do
          j--;
        while (lt.compare(pivot, array[j]) < 0);
        if (i >= j)
          break;
        tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
      }
      this.sort(array, start, i, lt);
      this.sort(array, i, end, lt);
    }
  }
942829
public void sortRows(Comparator<List<String>> comparator)
	{
		if(data.isEmpty())
			return;
		
		Collections.sort(data, comparator);
	}
378396
public static double median(double[] data, int begin, int end) {
    final int length = end - begin;
    assert (length > 0);
    // Integer division is "floor" since we are non-negative.
    final int left = begin + ((length - 1) >> 1);
    quickSelect(data, begin, end, left);
    if(length % 2 == 1) {
      return data[left];
    }
    else {
      quickSelect(data, left + 1, end, left + 1);
      return data[left] + .5 * (data[left + 1] - data[left]);
    }
  }
563513
@Override
	public int compareTo(ValueArray<ShortValue> o) {
		ShortValueArray other = (ShortValueArray) o;

		int min = Math.min(position, other.position);
		for (int i = 0; i < min; i++) {
			int cmp = Short.compare(data[i], other.data[i]);

			if (cmp != 0) {
				return cmp;
			}
		}

		return Integer.compare(position, other.position);
	}
138010
private static void quickSort(int[] data, final int start, final int end, IntComparator comp) {
    final int len = end - start;
    final int last = end - 1;
    if(len < INSERTION_THRESHOLD) {
      insertionSort(data, start, end, comp);
      return;
    }

    // Choose pivots by looking at five candidates.
    final int seventh = (len >> 3) + (len >> 6) + 1;
    final int m3 = (start + end) >> 1; // middle
    final int m2 = m3 - seventh;
    final int m1 = m2 - seventh;
    final int m4 = m3 + seventh;
    final int m5 = m4 + seventh;

    // Explicit (and optimal) sorting network for 5 elements
    // See Knuth for details.
    sort5(data, m1, m2, m3, m4, m5, comp);

    // Choose the 2 and 4th as pivots, as we want to get three parts
    // Copy to variables v1 and v3, replace them with the start and end
    // Note: do not modify v1 or v3 until we put them back!
    final int lpivot = data[m2];
    final int rpivot = data[m4];
    data[m2] = data[start];
    data[m4] = data[last];

    // A tie is when the two chosen pivots are the same
    final boolean tied = comp.compare(lpivot, rpivot) == 0;

    // Insertion points for pivot areas.
    int left = start + 1;
    int right = last - 1;

    // Note: we merged the ties and no ties cases.
    // This likely is marginally slower, but not at a macro level
    // And you never know with hotspot.
    for(int k = left; k <= right; k++) {
      final int tmp = data[k];
      final int c = comp.compare(tmp, lpivot);
      if(c == 0) {
        continue;
      }
      else if(c < 0) {
        // Traditional quicksort
        data[k] = data[left];
        data[left] = tmp;
        left++;
      }
      else if(tied || comp.compare(tmp, rpivot) > 0) {
        // Now look at the right. First skip correct entries there, too
        while(true) {
          final int tmp2 = data[right];
          if(comp.compare(tmp2, rpivot) > 0 && k < right) {
            right--;
          }
          else {
            break;
          }
        }
        // Now move tmp from k to the right.
        data[k] = data[right];
        data[right] = tmp;
        right--;
        // Test the element we just inserted: left or center?
        if(comp.compare(data[k], lpivot) < 0) {
          final int tmp2 = data[k];
          data[k] = data[left];
          data[left] = tmp2;
          left++;
        } // else: center. cannot be on right.
      }
    }
    // Put the pivot elements back in.
    // Remember: we must not modify v1 and v3 above.
    data[start] = data[left - 1];
    data[left - 1] = lpivot;
    data[last] = data[right + 1];
    data[right + 1] = rpivot;
    // v1 and v3 are now safe to modify again. Perform recursion:
    quickSort(data, start, left - 1, comp);
    // Handle the middle part - if necessary:
    if(!tied) {
      // TODO: the original publication had a special tie handling here.
      // It shouldn't affect correctness, but probably improves situations
      // with a lot of tied elements.
      quickSort(data, left, right + 1, comp);
    }
    quickSort(data, right + 2, end, comp);
  }
189856
public static double median(int[] values) {
        if (values.length == 0)
            throw new IllegalArgumentException("No median in an empty array");        
        int[] sorted = Arrays.copyOf(values, values.length);
        Arrays.sort(sorted);
        return sorted[sorted.length/2];
    }
844347
public float[] toWraparoundOrder(float data[], int i0, int stride) {
    checkData(data,i0,stride);
    float newdata[] = new float[2*n];
    int nh = n/2;
    newdata[0]   = data[i0];
    newdata[1]   = 0.0f;
    newdata[n]   = data[i0+stride*nh];
    newdata[n+1] = 0.0f;
    for(int i=1; i<nh; i++){
      newdata[2*i]      = data[i0+stride*i];
      newdata[2*i+1]    = data[i0+stride*(n-i)];
      newdata[2*(n-i)]  = data[i0+stride*i];
      newdata[2*(n-i)+1]=-data[i0+stride*(n-i)]; }
    return newdata; }
84470
public static char median(final char a, final char b, final char c) {
        if ((a >= b && a <= c) || (a >= c && a <= b)) {
            return a;
        } else if ((b >= a && b <= c) || (b >= c && b <= a)) {
            return b;
        } else {
            return c;
        }
    }
653492
public <T extends Evaluation> T evaluate(JavaRDD<DataSet> data) {
        return evaluate(data, null);
    }
524166
def median(data):
    
    data = sorted(data)
    n = len(data)
    if n == 0:
        raise StatisticsError("no median for empty data")
    if n % 2 == 1:
        return data[n // 2]
    else:
        i = n // 2
        return (data[i - 1] + data[i]) / 2
1334049
public static Statistics statisticsOf(List<Statistics> data) {
        if (data.isEmpty())
            return null;
        
        Iterator<Statistics> iterator = data.iterator();
        if (!iterator.hasNext()) {
            return null;
        }
        Statistics first = null;
        while (first == null && iterator.hasNext()) {
            first = iterator.next();
        }
        if (first == null)
            return null;
        
        int count = first.getCount();
        double min = first.getMinimum().doubleValue();
        double max = first.getMaximum().doubleValue();
        double total = first.getAverage() * first.getCount();
        double totalSquare = (first.getStdDev() * first.getStdDev() + first.getAverage() * first.getAverage()) * first.getCount();
        
        while (iterator.hasNext()) {
            Statistics stats = iterator.next();
            if (stats.getMaximum().doubleValue() > max)
                max = stats.getMaximum().doubleValue();
            if (stats.getMinimum().doubleValue() < min)
                min = stats.getMinimum().doubleValue();
            total += stats.getAverage() * stats.getCount();
            totalSquare += ( stats.getStdDev() * stats.getStdDev() + stats.getAverage() * stats.getAverage() ) * stats.getCount();
            count += stats.getCount();
        }
        
        double average = total/count;
        double stdDev = Math.sqrt(totalSquare / count - average * average);
        
        return new StatisticsImpl(count, min, max, average, stdDev);
    }
850405
public static <E extends Comparable<E>> void sort(E[] intArray) {
        Quicksort.sort(intArray, 0, intArray.length - 1 , false);
    }
8218
@CheckResult
    @NonNull
    public final Data<T> sort(@NonNull Comparator<? super T> comparator) {
        return new SortData<>(this, comparator);
    }