顺序统计量和中位数——线性时间的选择算法
2014-01-17 18:00
369 查看
一、求最大最小值
即遍历一次,然后依次跟当前最大或最小的比较一下,遍历结束,则选择结束。
(源代码来自网上)
二、求第i个顺序统计量
就是求集合中第i小的元素
第一种办法是先排序,然后直接索引。但是基于比较的排序的执行时间底线是nlogn。而非基于比较的排序又需要各种条件。
第二种分区算法,每执行一次能够找出基准值的最终位置,即左边的值都不大于基准值,右边的值都不小于基准值,这从而让人想起了折半查找,分治思想。
三、最坏情况为线性时间的选择算法
上面期望时间线性是因为可能存在某种最坏的情况,每次分割元的位置都是导致一边没有元素,这样就不能够达到线性了,而为n 2,接下来的一些预先工作就是避免这种情况发生。
算法SELECT通过执行下列步骤来确定一个有n个元素的输入数组中的第i个小的元素。
1、将输入数组的n个元素划分为n/5组,每组5个元素,且至多有一个组由剩下的n mod 5个元素组成。
2、寻找n/5个组中每一组的中位数。(方法首先对每组中的元素进行插入排序,然后从排序过的序列中选出中位数)
3、对第2步中找出的n/5个中位数,递归调用SELECT找出其中位数x。(如果有偶数个中位数,根据约定,x是下中位数。)
4、利用修改过的PARTITION过程,按中位数的中位数x对输入数组进行划分。让k比划分低区的元素多1,所以x是第k小的元素,并且有n-k个元素在划分的高区。
5、如果i=k,则返回x,否则,如果i<k,则在低区递归调用SELECT以找出第i小的元素,如果i>k,则在高区找第(i-k)个最小元素。
![](http://images.cnitblog.com/blog/342726/201212/23201146-25c3fae08dde4e4789469807ef7b1fb3.jpg)
图中箭头指向表示大的数值指向小的数值,所以根据图可以看出,在x的右边,每一个包含5个元素的组中至少有3个元素大于x,x的左边,每一组中至少有3个元素小于x。(保证x分割一边必定有元素存在)
图中显示的中位数的中位数x的位置,每次选取x作为划分的好处是能够保证必定有一部分在x的一边。
所以算法最坏情况的递归公式可以写成:
![](http://images.cnitblog.com/blog/342726/201212/23202211-5ddbfed51b07407e893cdef07528ce44.jpg)
使用替换法可以得出T(n)<=cn。
即遍历一次,然后依次跟当前最大或最小的比较一下,遍历结束,则选择结束。
(源代码来自网上)
//得到最小值 int GetMin(int nData[], int nLen) { int nMin = nData[0]; //初始化nMin为第一个数据 for (int i = 1; i < nLen; ++i) //遍历数据一一同nMin比较 { if (nMin > nData[i]) { nMin = nData[i]; } } return nMin; //返回最小值 } //得到最大值 int GetMax(int nData[], int nLen) { int nMax = nData[0]; //初始化nMax为第二个数据 for (int i = 1; i < nLen; ++i) //遍历数据一一同nMax比较 { if (nMax < nData[i]) { nMax = nData[i]; } } return nMax; //返回nMax }
二、求第i个顺序统计量
就是求集合中第i小的元素
第一种办法是先排序,然后直接索引。但是基于比较的排序的执行时间底线是nlogn。而非基于比较的排序又需要各种条件。
第二种分区算法,每执行一次能够找出基准值的最终位置,即左边的值都不大于基准值,右边的值都不小于基准值,这从而让人想起了折半查找,分治思想。
//在区间[low, high)搜索第k小的元素 2: int RandomizedSearchK(int A[], int low, int high, int k) 3: { 4: if(low == high-1) 5: return A[low]; 6: 7: int r = Partition(A, low, high); //返回基准值索引 8: int n = r - low + 1; // A[low.....r]的元素个数 9: if (n == k) //基准值正好是第k小 10: return A[r]; 11: else if (n < k) 12: RandomizedSearchK(A, r+1, high, k - n); //查找基准值右边第k-n小 13: else 14: RandomizedSearchK(A, low, r, k); // 查找基准值左边第k小 15: }
三、最坏情况为线性时间的选择算法
上面期望时间线性是因为可能存在某种最坏的情况,每次分割元的位置都是导致一边没有元素,这样就不能够达到线性了,而为n 2,接下来的一些预先工作就是避免这种情况发生。
算法SELECT通过执行下列步骤来确定一个有n个元素的输入数组中的第i个小的元素。
1、将输入数组的n个元素划分为n/5组,每组5个元素,且至多有一个组由剩下的n mod 5个元素组成。
2、寻找n/5个组中每一组的中位数。(方法首先对每组中的元素进行插入排序,然后从排序过的序列中选出中位数)
3、对第2步中找出的n/5个中位数,递归调用SELECT找出其中位数x。(如果有偶数个中位数,根据约定,x是下中位数。)
4、利用修改过的PARTITION过程,按中位数的中位数x对输入数组进行划分。让k比划分低区的元素多1,所以x是第k小的元素,并且有n-k个元素在划分的高区。
5、如果i=k,则返回x,否则,如果i<k,则在低区递归调用SELECT以找出第i小的元素,如果i>k,则在高区找第(i-k)个最小元素。
![](http://images.cnitblog.com/blog/342726/201212/23201146-25c3fae08dde4e4789469807ef7b1fb3.jpg)
图中箭头指向表示大的数值指向小的数值,所以根据图可以看出,在x的右边,每一个包含5个元素的组中至少有3个元素大于x,x的左边,每一组中至少有3个元素小于x。(保证x分割一边必定有元素存在)
图中显示的中位数的中位数x的位置,每次选取x作为划分的好处是能够保证必定有一部分在x的一边。
所以算法最坏情况的递归公式可以写成:
![](http://images.cnitblog.com/blog/342726/201212/23202211-5ddbfed51b07407e893cdef07528ce44.jpg)
使用替换法可以得出T(n)<=cn。
相关文章推荐
- 算法导论:第9章 中位数和顺序统计量_2最坏情况为线性时间的选择算法
- 算法导论:第9章 中位数和顺序统计量_1期望为线性时间的选择算法
- 算法导论-第九章-中位数和顺序统计量:最坏情况为线性时间的选择算法C++实现
- 第九章 中位数和顺序统计量 9.2 期望为线性时间的选择算法
- 第九章 中位数和顺序统计量 9.2 期望为线性时间的选择算法
- 最坏情况为线性时间的选择算法
- 寻找 最小的k个数 线性选择算法 平均时间复杂度 O(n)
- (基于Java)算法之最坏情况下的线性时间选择
- 算法导论第9章最坏情况为线性时间的选择算法
- Java 期望为线性时间的选择算法
- 最坏情况为线性时间的选择算法之Python实现
- 算法探究:线性时间选择问题
- 算法笔记——【分治法】线性时间选择
- 经典算法之线性时间选择的C实现方法
- 算法探究:线性时间选择问题
- 线性时间选择算法
- 线性时间选择 5元组选中位数法
- CLRS 9.2期望为线性时间的选择算法
- 算法探究:线性时间选择问题
- 期望为线性时间的选择算法randomizedSelect