算法 {快速選擇算法(std::nth_element)}

算法 {快速選擇算法(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]`;
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值