As Wikipedia says, the median median is theoretically o (N), but it is not used in practice because the overhead of finding βgoodβ reference points makes it too slow. http://en.wikipedia.org/wiki/Selection_algorithm
Here is the Java source for the Quickselect algorithm to find the kth element in an array:
/** * Returns position of k'th largest element of sub-list. * * @param list list to search, whose sub-list may be shuffled before * returning * @param lo first element of sub-list in list * @param hi just after last element of sub-list in list * @param k * @return position of k'th largest element of (possibly shuffled) sub-list. */ static int select(double[] list, int lo, int hi, int k) { int n = hi - lo; if (n < 2) return lo; double pivot = list[lo + (k * 7919) % n]; // Pick a random pivot // Triage list to [<pivot][=pivot][>pivot] int nLess = 0, nSame = 0, nMore = 0; int lo3 = lo; int hi3 = hi; while (lo3 < hi3) { double e = list[lo3]; int cmp = compare(e, pivot); if (cmp < 0) { nLess++; lo3++; } else if (cmp > 0) { swap(list, lo3, --hi3); if (nSame > 0) swap(list, hi3, hi3 + nSame); nMore++; } else { nSame++; swap(list, lo3, --hi3); } } assert (nSame > 0); assert (nLess + nSame + nMore == n); assert (list[lo + nLess] == pivot); assert (list[hi - nMore - 1] == pivot); if (k >= n - nMore) return select(list, hi - nMore, hi, k - nLess - nSame); else if (k < nLess) return select(list, lo, lo + nLess, k); return lo + k; }
I did not include the source of the comparison and swap methods, so it's easy to change the code to work with Object [] instead of double [].
In practice, you can expect the above code to be o (N).
Adam Gawne-Cain Dec 31 '15 at 23:09 2014-12-31 23:09
source share