输出前m大个数,时间复杂度O(n+mlog(m))

#include
using namespace std;

void swapM(int &a, int &b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

//用治处理  O(n+mlog(m))
//用O(n)把m大个数挪到右边,然后对这m个数排序再输出
void QuickSort(int a[], int s, int e)
{
    if(s >= e)
        return;
    int k = a[s];
    int i = s, j = e;
    while(i != j)
    {
        while(j > i && a[j] >= k)
            --j;
        swapM(a[i],a[j]);
        while(i < j && a[i] <= k)
            ++i;
        swapM(a[i],a[j]);
    }
    QuickSort(a,s,i-1);
    QuickSort(a,i+1,e);
}
//把数组(或数组的一部分)前k大的都弄到最右边
void arrangeRight(int *a, int s, int e, int k)
{
    if(s >= e)
        return;
    if(k == e-s+1)
        return;
    int i = s;
    int j = e;
    int key = a[s];

    while(i != j)
    {
         while(i < j && a[j] >= key)
             --j;
         swapM(a[i],a[j]);
         while(i < j && a[i] <= key)
             ++i;
         swapM(a[i],a[j]);
    }
    //如果右边的数刚好为e-i+1为k个
    if(k == e - i + 1)
        return;
    //右边的数大于k个
    else if(k < e - i + 1)
    {
        arrangeRight(a,i+1,e,k);
    }
    //右边的数小于k个,需要左边取出k - (e-i+1)个
    else
    {
         arrangeRight(a,s,i-1,k-e+i-1);
    }
}

void printM(int *a, int n, int m)
{
     //O(N)时间内先把m大的都弄到数组最右边
     arrangeRight(a,0,n-1,m);
    //对这m个数排序
    QuickSort(a,n-m,n-1);
    //输出
    while(m--)
    {
        cout << a[--n] << " ";
    }
    cout << endl;
}
int main()
{
    int a[] = {1,4,7,2,5,8,3,6,9};
    printM(a,9,4);
    system("pause");
    return 0;
}

你可能感兴趣的:(算法)