求100W个数中的前K个最大的数

来源:互联网 发布:iphone自动切换网络 编辑:程序博客网 时间:2024/05/24 06:12
#include<iostream>#include<windows.h>using namespace std;//挨个遍历排序:100w个数太多,内存不够,而且遍历排序效率太低//建大堆:只能选出最大的那个数//可选方案:建K个数的小堆//首先取这100w个数中的前K个数建立最小堆,即长度为K的数组的首元素为最小的元素//然后依次取剩下的元素,和首元素进行比较,如果比首元素大则替换,然后继续排最//小堆,让最小的数排在首元素位置,继续比较#define  M 100000#define  K 10////向下调整成最小堆void AdjustDown(int parent, int arr[]){    int child = parent * 2 + 1;    while (child<K)    {        if (child+1<K&&arr[child]>arr[child + 1] )//找结点左右较小的孩子,注意右孩子不能为空        {            child += 1;        }        if (arr[parent]>arr[child])//找结点左右较小的孩子        {            swap(arr[parent], arr[child]);            parent = child;            child = parent * 2 + 1;//重新当成一棵树访问        }        else            break;    }}//取出前K个数并保存——生成最小堆——M中剩下的数和堆顶元素比较void GetKMaxNum(int array[], int top[]){      //取出100W个数中前K个数保存到top数组    for (int idx = 0; idx < K; idx++)    {        array[idx] = top[idx];    }    //将top数组生成最小堆    for (int idx = (K - 2) >> 1; idx>=0; --idx)    {        AdjustDown(idx, top);//从倒数第一个非尾结点的位置开始调整    }    //取array里面剩下的数和top里面的堆顶元素进行比较,如果比堆顶元素大,则替换,    //然后再次调整成最小堆,则堆里的元素是最大的前K 个元素    for (int idx = K ; idx <M; ++idx)    {           if (top[0] < array[idx])        {            top[0] = array[idx];            AdjustDown(0, top);//从首元素位置继续调整,使之成为最小堆        }    }}void Print(int top[]){    int count = 0;    for (int i = 0; i < K; i++)    {        cout << top[i] << "   ";        count++;        if (count % 5 == 0)        {            cout << endl;        }    }    cout << endl;}void Test(){    int array[M] = { 0 };    int top[K] = { 0 };    for (int i = 0; i < M; i++)    {        array[i] = i;    }    array[10000] = 9999999;    array[M-100] = 199999;    array[M-5] = 22222222;    GetKMaxNum(array, top);    Print(top);}int main(){    Test();    system("pause");    return 0;}

这里写图片描述

2 0
原创粉丝点击