//*******************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;
}