快速选择(quick select) + 线性时间选择(linear-time select) - 求出n个数中第k大的数
2014-10-09 22:41
567 查看
原文链接:/article/8181498.html
利用快速排序中partition函数,很容易求出n个数中第k大的数,因此在划分后如下图。
![](http://img.my.csdn.net/uploads/201301/26/1359155873_1039.jpg)
左半(包括q)有j = q - p + 1个元素。如果k < j,只需要在左半找第k大元素;如果k > j,需要在右半找第k - j大元素。可以证明,期望时间复杂度为O(n)。
快速选择在期望意义下是线性的,事实上还存在最坏情况线性的算法。它由Blum, Floyd, Pratt, Rivest和Tarjan于1973年提出。
它的思想是:pivot不是随机选择,而是采取某种确定性的策略,使得每次递归调用后保证长度至少缩短为原来的a倍(a < 1)。这样,T(n)<= T(an)+O(n),由主定理得T(n)=O(n)。
![](http://img.my.csdn.net/uploads/201301/26/1359157080_9712.jpg)
如图8.1.2所示,把所有元素分成5个一组共约n/5组,每组用暴力法求出中位数(图中为中心行白点所示),一共有n/5个中位数。用递归法求出这n/5个数的中位数x,则所有k个中位数中至少有约n/10个数比x小。由于每个中位数在自己组中至少有3个数不比它大(也就不会比x大),因此至少有3(n/10) = 0.3n个数比x小。更精细的分析指出,当n>=75时至少有n/4个数比x小。同理,也至少有n/4个数比x大。求n/5个数的中位数需要T(n/5)的时间,而划分后的选择不超过T(3n/4),因此T(n)>=T(n/5)+T(3n/4)+O(1),解为T(n)=O(n)。
利用快速排序中partition函数,很容易求出n个数中第k大的数,因此在划分后如下图。
![](http://img.my.csdn.net/uploads/201301/26/1359155873_1039.jpg)
左半(包括q)有j = q - p + 1个元素。如果k < j,只需要在左半找第k大元素;如果k > j,需要在右半找第k - j大元素。可以证明,期望时间复杂度为O(n)。
int partition ( int p , int q) { int x = a[p], i = p; for(j = p +1; j <= q; j ++) if(a[j] <= x) swap (a[++i], a[j]); swap (a[p], a[i]); return i; } int select ( int p , int r , int k){ if(p == r) return p; int i = p + rand()%(r–p+1); swap (a[i], a[p]); int q = partition (p , r); int j = q– p + 1; if(k == j) return q; else if(k < j) return select (p , q , k); else select (q+1 , r , k-j); }
快速选择在期望意义下是线性的,事实上还存在最坏情况线性的算法。它由Blum, Floyd, Pratt, Rivest和Tarjan于1973年提出。
它的思想是:pivot不是随机选择,而是采取某种确定性的策略,使得每次递归调用后保证长度至少缩短为原来的a倍(a < 1)。这样,T(n)<= T(an)+O(n),由主定理得T(n)=O(n)。
![](http://img.my.csdn.net/uploads/201301/26/1359157080_9712.jpg)
如图8.1.2所示,把所有元素分成5个一组共约n/5组,每组用暴力法求出中位数(图中为中心行白点所示),一共有n/5个中位数。用递归法求出这n/5个数的中位数x,则所有k个中位数中至少有约n/10个数比x小。由于每个中位数在自己组中至少有3个数不比它大(也就不会比x大),因此至少有3(n/10) = 0.3n个数比x小。更精细的分析指出,当n>=75时至少有n/4个数比x小。同理,也至少有n/4个数比x大。求n/5个数的中位数需要T(n/5)的时间,而划分后的选择不超过T(3n/4),因此T(n)>=T(n/5)+T(3n/4)+O(1),解为T(n)=O(n)。
相关文章推荐
- 快速选择(quick select) + 线性时间选择(linear-time select) - 求出n个数中第k大的数
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
- 快速选择(QuickSelect)的平均时间复杂度分析
- 线性时间选择:从n个元素中找出第k小的元素
- 线性时间冰山查询算法(Linear-time Iceberg Query Algorithm )
- 线性时间选择问题-第k小(大)问题-递归与分治
- 期望为线性时间的选择算法randomizedSelect
- Quick Select Algorithm 快速选择算法
- 快速选择排序(quickselect)--基于quicksort
- 最快的高斯模糊(线性时间)Fastest Gaussian Blur (in linear time)
- 线性时间排序 Sorting in linear time O(n)
- 【数据结构笔记】快速排序(quick_sort)和快速选择(quick_select)--Python2.7
- 快速选择(quick_select) 算法分析
- 快速排序与快速选择算法(quick sort and quick select algorithm)
- 分治算法;随机化划分函数;快速排序;线性时间选择第K小元素;快速排序平均时间复杂度nlgn;
- [置顶] 递归与分治策略-2.9.2线性时间选择(取中位数的中位数基准)(第k小问题)
- 期望为线性时间的选择算法RANDOM_SELECT
- 选择问题:线性时间内找到序列的第k小的元素
- 分治算法:线性时间选择第k大小的数字 && STL函数:nth_element()