线性时间选择
2011-03-01 14:08
162 查看
线性时间选择
出自:http://algorithm.chaoskey.com/02/07【题目 】:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序 的) 【思路 】:如果能在线性时间内找到一个划分基准 ,使得按这个基准所划分出的2个子数组的长度都至少为原数组长度的ε倍(0<ε<1是某个正常数),那么就可以在最坏情况下用O(n)时间完成选择任务。 例如 :若ε=9/10,算法递归调用所产生的子数组的长度至少缩短1/10。所以,在最坏情况下,算法所需的计算时间T(n)满足递归式T(n)≤T(9n/10)+O(n) 。由此可得T(n)=O(n)。 【具体解题 】:这里我们将所有的数(n个),以每5个划分为一组,共[n/5]组(将不足五个的那组忽略);然后用任意一种排序算法 (因为只对五个数进行排序,所以任取一种排序法就可以了,这里我选用冒泡排序),将每组中的元素排好序再分别取每组的中位数,得到[n/5]个中位数;再 取这[n/5]个中位数的中位数(如果n/5是偶数,就找它的2个中位数中较大的一个)作为划分基准,将全部的数划分为两个部分,小于基准的在左边,大于 等于基准的放右边。 在这种情况下,找出的基准x至少比3(n-5)/10个元素大,因为在每一组中有2个元素小于本组的中位数,中位数处于1/2*[n/5-1],即n/5 个中位数中又有(n-5)/10个小于基准x。同理,基准x也至少比3(n-5)/10个元素小。而当n≥75时,3(n-5)/10≥n/4所以按此基 准划分所得的2个子数组的长度都至少缩短1/4。 程序代码如下: #include<iostream.h> #include<stdlib.h> #include<time.h> #define MAX_VALUE 10000 #define random() rand()%MAX_VALUE #define N 10000 int a ; class Find { public: void bubble(int first,int end) // 冒泡排序 { for(int flag=first;flag<end;flag++) for(int i=end;i>flag;i--) if(a[i]<a[i-1]) { int t=a[i]; a[i]=a[i-1]; a[i-1]=t; } } int partition(int p,int r,int x) // 数组 a 中从 a[p] 到 a[r] 的元素按照 x 划分 , 大于 x 的在左边 , 小于 x 的在右边 { int i,j; for(i=p,j=r;i<j;i++) { if(a[i]>x) { while(i<j&&a[j]>x) j--; if(i!=j){ int t=a[i]; a[i]=a[j]; a[j]=t; j--; } } } return i-1; } int select(int p,int r,int k) // 寻找中位数 { if(r-p<5){ bubble(p,r); return a[p+k-1]; } for(int i=0;i<(r-p-4)/5;i++) { int s=p+5*i,t=s+4; bubble(s,t); int temp=a[p+i]; a[p+i]=a[s+2]; a[s+2]=temp; } int x=select(p,p+(r-p-4)/5,(r-p+6)/10); i=partition(p,r,x); int j=i-p+1; if(k<=j) return select(p,i,k); else return select(i+1,r,k-j); } }; void main() { clock_t start,end; double elapsed; srand((int)time(NULL)); for(int k=0;k<N;k++) { a[k]=random(); cout<<a[k]<<"/t"; } cout<<endl; start=clock(); Find f; int n=5000; cout<<"The No."<<n<<" is :"<<f.select(0,N-1,n)<<endl; end=clock(); elapsed=((double)(end-start));///CLOCKS_PER_SEC; cout<<"Time: "<<elapsed<<endl; } 这个题目关键在寻找划分基准,从而提高寻找效率,时间复杂度为o(n); |
相关文章推荐
- 算法探究:线性时间选择问题
- 线性时间选择
- 期望为线性时间的选择算法randomizedSelect
- (p123)最坏情况为线性时间的选择算法
- 线性时间选择问题-第k小(大)问题-递归与分治
- (基于Java)算法之最坏情况下的线性时间选择
- 线性期望时间选择问题C语言
- 线性时间选择1
- 算法探究:线性时间选择问题
- CLRS 9.2期望为线性时间的选择算法
- 线性时间选择(TOP K)
- 第九章 中位数和顺序统计量 9.2 期望为线性时间的选择算法
- 最坏情况为线性时间的选择算法---算法导论学习笔记(2)
- <算法导论>第九章3 最坏情况线性时间的选择
- 线性时间选择2
- 0006算法笔记——【分治法】线性时间选择
- 最坏情况为线性时间的选择算法之Python实现
- 快速选择(quick select) + 线性时间选择(linear-time select) - 求出n个数中第k大的数
- 算法探究:线性时间选择问题
- CLRS 9.3最坏情况为线性时间的选择算法