Jump to content

Floyd–Rivest algorithm

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Cydebot (talk | contribs) at 05:18, 6 October 2018 (Robot - Removing category Eponymous scientific concepts per CFD at Wikipedia:Categories for discussion/Log/2018 September 22.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Floyd–Rivest
ClassSelection algorithm
Data structureArray
Average performancen + min(k, n - k) + O(n1/2)

In computer science, the Floyd-Rivest algorithm is a selection algorithm developed by Robert W. Floyd and Ronald L. Rivest that has an optimal expected number of comparisons within lower-order terms. It is functionally equivalent to quickselect, but runs faster in practice on average. [1] It has an expected running time of O(n) and an expected number of comparisons of n + min(k, n - k) + O(n1/2).

The algorithm was originally presented in a Stanford University technical report containing two papers, where it was referred to as SELECT and paired with PICK, or median of medians. [2] It was subsequently published in Communications of the ACM, Volume 18: Issue 3.

Algorithm

The Floyd-Rivest algorithm is a divide and conquer algorithm, sharing many similarities with quickselect. It uses sampling to help partition the list into three sets. It then recursively selects the kth smallest element from the appropriate set.

The general steps are:

  1. Select a small random sample S from the list L.
  2. From S, recursively select two elements, u and v, such that u < v. These two elements will be the pivots for the partition and are expected to contain the kth smallest element of the entire list between them (in a sorted list).
  3. Using u and v, partition S into three sets: A, B, and C. A will contain the elements with values less than u, B will contain the elements with values between u and v, and C will contain the elements with values greater than v.
  4. Partition the remaining elements in L (that is, the elements in L - S) by comparing them to u or v and placing them into the appropriate set. If k is smaller than half the number of the elements in L rounded up, then the remaining elements should be compared to v first and then only to u if they are smaller than v. Otherwise, the remaining elements should be compared to u first and only to v if they are greater than u.
  5. Based on the value of k, apply the algorithm recursively to the appropriate set to select the kth smallest element in L.

Pseudocode version

The following pseudocode sorts the elements between left and right in ascending order, such that for some value k, where leftkright, the kth element in the list will contain the (k - left + 1)th smallest value:

 // left is the left index for the interval
 // right is the right index for the interval
 // k is the desired index value, where array[k] is the (k+1)th smallest element when left = 0
 function select(array, left, right, k)
     while right > left
         // use select recursively to sample a smaller set of size s
         // the arbitrary constants 600 and 0.5 are used in the original
         // version to minimize execution time
         if right - left > 600
             n := right - left + 1
             i := k - left + 1
             z := ln(n)
             s := 0.5 * exp(2 * z/3)
             sd := 0.5 * sqrt(z * s * (n - s)/n) * sign(i - n/2)
             newLeft = max(left, k - i * s/n + sd)
             newRight = min(right, k + (n - i) * s/n + sd)
             select(array, newLeft, newRight, k)
         // partition the elements between left and right around t
         t := array[k] 
         i := left
         j := right
         swap array[left] and array[k]
         if array[right] > t 
             swap array[right] and array[left]
         while i < j
             swap array[i] and array[j]
             i := i + 1
             j := j - 1
             while array[i] < t
                 i := i + 1
             while array[j] > t
                 j := j - 1
         if array[left] = t
             swap array[left] and array[j]
         else
             j := j + 1
             swap array[j] and array[right]
         // adjust left and right towards the boundaries of the subset
         // containing the (k - left + 1)th smallest element
         if j ≤ k
             left := j + 1
         if k ≤ j 
             right := j - 1

See also

References

  1. ^ Floyd, Robert W.; Rivest, Ronald L. (1975). "Algorithm 489". Comm. ACM. 18 (3): 173. doi:10.1145/360680.360694.
  2. ^ "Two papers on the selection problem: Time Bounds for Selection and Expected Time Bounds for Selection" CS-TR-73-349, Stanford Computer Science Technical Reports and Technical Notes, April 1973
  • Floyd, R. W.; Rivest, R. L. (March 1975). "Expected time bounds for selection". Communications of the ACM. 18 (3): 165–172. doi:10.1145/360680.360691.
  • Kiwiel, K. C. (2005). "On Floyd and Rivest's SELECT algorithm". Theoretical Computer Science. 347: 214–238. doi:10.1016/j.tcs.2005.06.032.
  • "A probabilistic analysis of the Floyd-Rivest expected time selection algorithm" (2002), by Alexandros V. Gerbessiotis, Constantinos J. Siniolakis, Aghia Paraskevi