查找最小的k个元素-快排、中位数选择(上)

查找最小的k个元素(数组)
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

//coder:LEE

//20120304
#include<iostream>
#include<CASSERT>
#include <ctime>
#include <CWINDOW.H>
using namespace std;
//数组b中保存前k个值,然后遍历数组a,将b中最大的值用a中小于他的值替换
//时间复杂度:o(n-k^2+k)
void MinK(int* a,int n,int k)
{
assert(a!=NULL&&k>0&&n>0);
int* b=new int[k];
for(int i=0;i<k;i++)
b[i]=a[i];
for (;i<n;i++)
{
int max=b[0];
int maxTag=0;
for (int j=1;j<k;j++)
{
if (b[j]>max)
{
max=b[j];
maxTag=j;
}
}
if(a[i]<max)
b[maxTag]=a[i];
}
// for(i=0;i<k;i++)
// cout<<b[i]<<"  ";
// cout<<endl;
}
void Swap(int *a,int *b)
{
int t=*a;
*a=*b;
*b=t;
}
int Partition(int *A,int p,int r)
{
int x=A[r];
int i=p-1;
for (int j=p;j<=r-1;j++)
{
if (A[j]<=x)
{
i+=1;
Swap(&A[i],&A[j]);
}
}
Swap(&A[i+1],&A[r]);
return i+1;
}
void QuickSort(int *A,int p,int r)//快速排序
{
if(p<r)
{
int q=Partition(A,p,r);
QuickSort(A,p,q-1);
QuickSort(A,q+1,r);
}
}
int RandomizedPartition(int *A,int p,int r)
{
srand(time(0));
int randNumber=rand()%(r-p+1)+p;
Swap(&A[randNumber],&A[r]);
return Partition(A,p,r);
}
void RandomizedQuickSort(int *A,int p,int r)
{
if(p<r)
{
int q=RandomizedPartition(A,p,r);
RandomizedQuickSort(A,p,q-1);
RandomizedQuickSort(A,q+1,r);
}
}
void RandomizedSelect(int *A,int p,int r,int i)//时间复杂度O(n)
{
if(p==r)
return;
int q=RandomizedPartition(A,p,r);
int k=q-p+1;
if(i==k)
return;
else if(i<k)
RandomizedSelect(A,p,q-1,i);
else
RandomizedSelect(A,q+1,r,i-k);


}


void InsertionSort(int *A,int p,int r)//插入排序
{
for (int j=p+1;j<=r;j++)
{
int key=A[j];
int i=j-1;
while(i>=p&&A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
}
}
int MedianFind(int *A,int p,int r)//选择中位数的中位数
{
int groups=(r-p)/5+1;
int remains=(r-p+1)-5*(groups-1);
int *median=new int[groups];
for(int i=0;i<groups;i++)
{
if (i!=groups-1)
{
InsertionSort(A,p+5*i,p+5*i+4);
median[i]=A[p+5*i+2];
}
else
{
InsertionSort(A,p+5*i,p+remains-1);
median[i]=A[p+5*i+remains/2];
}
}
// cout<<"groups;"<<endl;
// for(i=0;i<groups;i++)
// cout<<median[i]<<"  ";
// cout<<endl;
if(groups==1)
return median[0];
else
return MedianFind(median,0,groups-1);
return 0;
}
int MedianPartition(int *A,int p,int r,int n)
{
Swap(&A[n],&A[r]);//交换
return Partition(A,p,r);
}
void MedianSelect(int *A,int p,int r,int i)

if(p==r)
return;
int median=MedianFind(A,p,r);
for(int j=p;j<=r;j++)
if(median==A[j])//找到中位数的标号
break;
int q=MedianPartition(A,p,r,j);
int k=q-p+1;
if(i==k)
return;
else if(i<k)
MedianSelect(A,p,q-1,i);
else
MedianSelect(A,q+1,r,i-k);
}
int main()
{
const numbers=100000;
int data[numbers];
for (int i=0;i<numbers;i++)
{
data[i]=rand()%numbers;
}
cout<<"after:"<<endl;
double beg=GetTickCount();
MedianSelect(data,0,sizeof(data)/sizeof(int)-1,100);
double end=GetTickCount();
cout<<"time:"<<(end-beg)<<"ms"<<endl;
// for (i=0;i<sizeof(data)/sizeof(int);i++)
// cout<<data[i]<<" ";



/* int a1[]={2,8,7,1,3,5,6,4};
InsertionSort(a1,0,sizeof(a1)/sizeof(int)-1);
for (int j=0;j<sizeof(a1)/sizeof(int);j++)
{
cout<<a1[j]<<" ";
}


cout<<endl;
int data[100];
for (int i=0;i<100;i++)
{
data[i]=rand()%100;
}
RandomizedSelect(data,0,sizeof(data)/sizeof(int)-1,11);
for (i=0;i<sizeof(data)/sizeof(int);i++)
{
cout<<data[i]<<" ";
}
cout<<endl;


int a2[]={2,8,7,1,3,5,6,4};
RandomizedQuickSort(a2,0,sizeof(a2)/sizeof(int)-1);
for (int j=0;j<sizeof(a2)/sizeof(int);j++)
{
cout<<a2[j]<<" ";
}

int a1[]={1,2,3,4,5,6,7,8};
int k1=4;
MinK(a1,sizeof(a1)/sizeof(int),k1);
*/
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值