100w个数中找出最大的前k个数

//*******************100w个数中找出最大的前k个数***************************
//挨个遍历排序:100w个数太多,内存不够,而且遍历排序效率太低
//建大堆:只能选出最大的那个数
//可选方案:建K个数的小堆
//          首先取这100w个数中的前K个数建立最小堆,即长度为K的数组的首元素为最小的元素
//          然后依次取剩下的元素,和首元素进行比较,如果比首元素大则替换,然后继续排最
//          小堆,让最小的数排在首元素位置,继续比较
#define M 100000
#define K 100

//向下调整成最小堆
void AdjustDown( int parent , int * a )
{
                 int child = parent * 2 + 1;
                 while (child < K )
                {
                                 if (child + 1 < K && a [child] > a [child + 1])
                                {
                                                child++;
                                }
                                 if ( a [child] < a [ parent ])
                                {
                                                swap( a [child], a [ parent ]);
                                                 parent = child;
                                                child = parent * 2 + 1;
                                }
                                 else
                                {
                                                 break ;
                                }
                }
}
void GetKMaxNum( int array [], int top [])
{
                 assert ( K < M );

                 //取array数组里面的前K个数给top数组
                 for ( int i = 0; i < K ; i++)
                {
                                 top [i] = array [i];
                }

                 //建最小堆
                 for ( int i = (K - 2) / 2; i >= 0;i--)
                {
                                AdjustDown(i, top );
                }

                 //取array里面剩下的数和top里面的首元素进行比较,如果比首元素大,则替换,然后再次调整成最小堆
                 for ( int i = K; i < M ; i++)
                {
                                 if ( array [i]> top [0])
                                {
                                                 top [0] = array [i];
                                                AdjustDown(0, top );
                                }
                }

}
void Print( int * top )
{
                 int count = 0;
                 for ( int i = 0; i < K ; i++)
                {
                                cout << top [i] << "   " ;
                                count++;
                                 if (count % 6==0 )
                                {
                                                cout << endl;
                                }
                }
}

void Test()
{
                 int array[ M ] = { 0 };
                 int top[ K ] = { 0 };
                 for ( int i = 0; i < M ; i++)
                {
                                array[i] = i;
                }
                array[9] = 1111111;
                array[99] = 11111111;
                array[999] = 111111111;
                GetKMaxNum(array, top);
                Print(top);

}


int main()
{
                Test();
                 return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值