BFPTR算法(中位数的中位数算法)求n个数中第k大的数

来源:互联网 发布:淘宝店最高收入多少 编辑:程序博客网 时间:2024/04/30 10:52

        BFPTR算法求n个数中第k大(即第n-1-k小)的数,其思想是基于快速排序中对Partion的pivot值进行优化,快速排序中每一趟快排的pivot的选取一般是数组的首项或者尾项(数值比较随机),而BFPTR是每次选择5分中位数的中位数作为pivot进行下一趟快速排序的,这样做可以使算法的时间复杂度由最坏的O(n^2)变为O(n).

实现代码如下:

#include <iostream>using namespace std;const int maxn=1000;int a[maxn],n,k; //求有n个元素的数组a中第k大(第n-1-k小)的数void Insert_Sort(int a[],int l,int r){//由于只有5个数,插入排序即可    for(int i=l;i<=r;i++)    {        int tmp=a[i],j=i-1;        for(;j>=l&&tmp<a[j];j--) a[j+1]=a[j];        a[j+1]=tmp;    }}int Find_mid(int a[],int l,int r){//寻找中位数的中位数    if(l==r) return a[l];    int i=0,n=0;    for(int i=l;i<r-5;i+=5)    {        Insert_Sort(a,i,i+4); //每5个数按升序排列        n=i-l;        swap(a[l+n/5],a[i+2]); //将找到的中位数放在数组a的前面    }    //处理剩余元素    int res=r-i+1;    if(res>0)    {        Insert_Sort(a,i,i+res-1);        n=i-l;        swap(a[l+n/5],a[i+res/2]);    }    n/=5; //a[0..n]存放本趟分组的中位数    if(n<=1) return a[l]; //当中位数小于2个(下标n<=1)时直接返回较小的    return Find_mid(a,l,l+n); //大于2个时递归继续寻找中位数}int Find_pos(int a[],int l,int r,int mid){//找到中位数的中位数在a中的下标    for(int i=l;i<=r;i++)        if(a[i]==mid) return i;    return -1;}int Partion(int a[],int l,int r,int pos){//进行划分过程    swap(a[pos],a[l]); //将找到的中位数的中位数(即mid)换到数组a的最前面    int i=l,j=r;    int pivot=a[l];    while(i<j)    {        while(i<j&&a[j]>=pivot) j--;        a[i]=a[j];        while(i<j&&a[i]<=pivot) i++;        a[j]=a[i];    }    a[i]=pivot;    return i; //返回pivot(即mid值)的下标}int BFPTR(int a[],int l,int r,int k){    int mid=Find_mid(a,l,r); //寻找中位数的中位数    int pos=Find_pos(a,l,r,mid); //找到中位数的中位数在a中的下标    int i=Partion(a,l,r,pos);    int m=i-l+1; //m即为mid归位后在a中的位置    if(m==k) return a[i];    if(m>k) return BFPTR(a,l,i-1,k);    return BFPTR(a,i+1,r,k-m);}int main(){    while(cin>>n)    {        for(int i=0;i<n;i++) cin>>a[i];        cin>>k;        cout<<"The "<<k<<" number in the array is:"<<BFPTR(a,0,n-1,k)<<endl;        for(int i=0;i<n;i++) cout<<a[i]<<" ";        cout<<endl;    }    return 0;}/*输入:102 1 3 9 8 0 5 6 4 75输出:The 5 number in the array is:40 1 3 2 4 5 6 7 8 9*/





1 0
原创粉丝点击