最坏情况线性时间选择O(n) 收藏
来源:互联网 发布:windows预览体验计划 编辑:程序博客网 时间:2024/05/11 22:04
最坏情况线性时间选择O(n) 收藏
【题目】:给定线性序集中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[N];
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);
本文固定链接为:http://www.hinn.cn/2008/04/randomizedselect.html
- 最坏情况线性时间选择O(n) 收藏
- 最坏情况线性时间选择O(n)
- 最坏情况下为O(N)的线性时间选择
- 第九章中位数和顺序统计学 之 “寻找第i小元素之最坏情况线性时间的选择 最坏运行时间就为O(n)算法”
- 最坏情况下做O(n)选择
- 最坏情况线性时间的选择 java实现
- 最坏情况为线性时间的选择算法
- 最坏情况下的线性时间的选择算法
- CLRS 9.3最坏情况为线性时间的选择算法
- (p123)最坏情况为线性时间的选择算法
- 最坏情况为线性时间的选择算法
- 算法导论之最坏情况下为O(n)的选择算法
- <算法导论>第九章3 最坏情况线性时间的选择
- 算法导论第9章最坏情况为线性时间的选择算法
- (基于Java)算法之最坏情况下的线性时间选择
- 《算法导论》笔记 第9章 9.3最坏情况线性时间选择
- 算法之分治——最坏情况线性时间的选择
- 算法导论 最坏情况为线性时间的选择算法 9.3-8 9.3-9
- 决策树:排序问题的计算复杂性 收藏
- 二分(折半)查找算法 收藏
- 不使用栈后序遍历二叉树 收藏
- 线程安全集合
- 关于k分位数 收藏
- 最坏情况线性时间选择O(n) 收藏
- 求已知集合中某两个或三个元素之和等于确定值问题 收藏
- 并归排序法求逆序数 收藏
- 每周四十小时,你有多少是在为自己干活?
- Facebook应吸取谷歌经验避免重蹈雅虎覆辙
- HashTable和HashMap的区别 收藏
- 090912(星期六):MFC
- JS判断浏览器是否是关闭
- MonoDevelop正式迈入跨平台时代