【算法】第 n 小数 nth_element

20 篇文章 0 订阅
12 篇文章 0 订阅

STL 中取第 n 小数的算法 nth_element 的函数原型如下

template<class RandomAccessIterator>
void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);

算法说明:

1、功能:执行 nth_element 后,nth 所指位置的元素将是整个区间有序时在该处的元素。对 [first, nth) 中的任意迭代器 i 和 [nth, last) 中的任意迭代器 j,满足 !(*i > *j)。

2、要求:RandomAccessIterator 必须满足 ValueSwappable。*first 的类型必须满足 MoveConstructible 和 MoveAssignable。

3、复杂度:平均为线性。

源码如下:

template <class RandomAccessIterator>
void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) {
	while (last - first > 3) {
		RandomAccessIterator cut = unguarded_partition(first, last, Type(median(
			*first,
			*(first + (last - first) / 2),
			*(last - 1))));
		if (cut <= nth) {
			first = cut;
		} else {
			last = cut;
		}
	}
	insertion_sort(first, last);
}

其中的 unguarded_partition, median 和 insertion_sort 在之前介绍过,这里不再列出它们的源码。其中的 Type 由 RandomAccessIterator 的 traits 得到,这里简化了。函数中的 first 和 last 可能改变,当 [first, last) 区间大于3时就一直划分,划分是采用三者取中的方式以缓解输入时的糟糕情况,每次划分后产生两段,若右段起点 cut <= nth,则再对右段划分,否则对左段划分。直到区间长度小于等于3时,索性对这个小区间进行插入排序,注意 nth 始终在 [first, last) 中。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值