算法 {快速選擇算法(std::nth_element)}
快速選擇算法(std::nth_element)
定義
std::nth_element( A.begin(), A.begin() + K, A.begin() + N)
, 此时会有A[<K] <= A[K]; A[>K] >= A[K]
;
.
因为A[K] == 第(K+1)小元素
(可以用来求第X小元素);
.
因为A[<K] <= A[K]
(即他可以用来求前X小元素之和);
性质
求序列中的第K小數, 或者 求序列中的前K個最小的數是什麽;
.
如果用普通排序算法 他是O(N*log)
的, 而快速選擇算法是O(N)
的;
對於A[n]
, 通過std::nth_element( A, A+k, A+n)
后 (確保0 <= k < n
), 此時A[k]
就是第k+1
小數 而且A[0...k]<=A[k] && A[k...n)>=A[k]
, 但是注意 整個序列并不是有序的;
.
比如A = {1,2,2,2,3}; K=2
, 因爲第k+1=3
小數是2
, 所以nth_element( A.begin(), A.begin() + 2, A.end())
之後 數組會變成[x0,2,x1]
(x0<=2, x1>=2
), (比如可能A = [2,1,2,3,2]
);
例題
@LINK: https://editor.csdn.net/md/?articleId=136283729
;
筆記
Source-Code \text{ Source-Code} Source-Code
nth_element(_RAIter, _RAIter, _RAIter);
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
.
nth_element( ?, ?, ?)
equals to nth_element( ?, ?, ?, less<>())
;
Function \text{ Function} Function
nth_element( v.begin(), v.begin() + k, v.end());
.
将前
k
k
k小的元素, 放到数组的开头; 比如[4,6,5,3,2,1]
如果
k
=
3
k=3
k=3 则最终数组可能为[2,1,3, 5,4,6]
次序不唯一, 但前
3
3
3小的元素 肯定在最开头;
vector< T> v{ ...};
n = v.size();
k = [1, n-1];
@Define( S: the set of the smallest `k` elements in `v`);
nth_element( v.begin(), v.begin() + k, v.end());
. Now, `v[0,1,...,k-1]` would be `S` (the order of `v[0,1,...,k-1]` maybe not increasing);
@Delimiter
vector< int> v{ 6, 4, 3, 5, 1, 2};
nth_element( v.begin(), v.begin() + 3, v.end());
. Which is equivalent to `nth_element( v.begin(), v.begin() + 3, v.end(), less<>())`;
. Now, `v = [2,1,3, 5,4,6]`;
nth_element( v.begin(), v.begin() + 3, v.end(), greater<>());
. Now, `v = [4,6,5, 2,3,1]`;