public void Sort(string[] entries, Int32 first, Int32 last) { var length = last + 1 - first; while (length > 1) { if (length < InsertionLimit) { InsertionSort.Sort(entries, first, last); return; } Left = first; Right = last; pivot(entries); partition(entries); //[Note]Right < Left var leftLength = Right + 1 - first; var rightLength = last + 1 - Left; // // First recurse over shorter partition, then loop // on the longer partition to elide tail recursion. // if (leftLength < rightLength) { Sort(entries, first, Right); first = Left; length = rightLength; } else { Sort(entries, Left, last); last = Right; length = leftLength; } } }
private void pivot(string[] entries) { // // An odd sample size is chosen based on the log of the interval size. // The median of a randomly chosen set of samples is then returned as // an estimate of the true median. // var length = Right + 1 - Left; var logLen = (Int32)Math.Log10(length); var pivotSamples = 2 * logLen + 1; var sampleSize = Math.Min(pivotSamples, length); var last = Left + sampleSize - 1; // Sample without replacement for (var first = Left; first <= last; first++) { // Random sampling avoids pathological cases var random = Random.Next(first, Right + 1); Swap(entries, first, random); } InsertionSort.Sort(entries, Left, last); Median = entries[Left + sampleSize / 2]; }