Floyd–Rivest algorithm
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 log1/2 n). 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. AlgorithmThe 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:
By using |S| = Θ(n2/3 log1/3 n), we can get n + min(k, n − k) + O(n2/3 log1/3 n) expected comparisons. We can get n + min(k, n − k) + O(n1/2 log1/2 n) expected comparisons by starting with a small S and repeatedly updating u and v to keep the size of B small enough (O(n1/2 log1/2 n) at Θ(n) processed elements) without unacceptable risk of the desired element being outside of B. Pseudocode versionThe following pseudocode rearranges the elements between // 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) is while right > left do // 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 then 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 then swap array[right] and array[left] while i < j do swap array[i] and array[j] i := i + 1 j := j − 1 while array[i] < t do i := i + 1 while array[j] > t do j := j − 1 if array[left] = t then 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 then left := j + 1 if k ≤ j then right := j − 1 See alsoReferences
|
Portal di Ensiklopedia Dunia