您的位置:首页 > 其它

用堆排序实现线性时间查找前K大数字

2014-12-03 09:30 148 查看
1004. 寻找前k大的数(选做)

Total:339Accepted:44
   
Time Limit: 1sec    Memory Limit:256MB
Description

<b>选做</b><br>

你的任务是写一个程序来找出N个整数里面前K大的整数,输出按照降序排列。

你可以通过百度了解如何快速找出这K个整数,可以找到时间复杂度为O(N*lgK)的方法。

如果你实在搜不到,ftp上面有个txt文件大概讲了三种方法的思路,可以去看看。

如果面试问到了这个题,优先使用第一种思路,当然如果面试官允许你把三种思路都讲完的话,那也是不错的(前提是你不要自己打脸…要理解它们的复杂度为什么是那样)。

Input

输入有多个测试用例,每个测试用例是两行:

第1行是两个整数N和K,中间用空格隔开(N ≥ K)

第2行有N个整数,每两个数字中间用空格隔开

输入以EOF结束

Output

对于每一个测试用例,输出一行,K个整数,就是它的前K大的整数,按照降序排列输出,每两个数字之间用空格隔开,最后一个数字后面没有空格,有换行。

Sample Input
Copy sample input to clipboard

5 23 2 4 1 5


Sample Output

5 4


/*包括去重复和不去重复两种,主要是建立最小堆
*/

#include <iostream>
#include <cstdio>
#include <memory.h>

using namespace std;

//调整堆
void HeapAdjust(int *a, int ¤t, int low, int high)
{
int large;
large = 2 * low + 1; //左儿子
while (large <= high) {
if (large < high && a[large] > a[large+1])
large++;
if (current <= a[large])
break;
else {
//继续调整堆
a[low] = a[large];
low = large;
large = 2 * low + 1;
}
}
a[low] = current;
}

void build_heap(int *a, int size)
{
int current;
//建堆,从(size - 2)/2开始 到0
for (int low = (size - 2)/2; low >= 0; low--)
{
//记录当前值
current = a[low];
HeapAdjust(a, current, low, size - 1);
}
}
void HeapSort(int *a, int size)
{
int current;
//建立堆
build_heap(a, size);

for (int i = size - 1; i > 0; i--)
{
current = a[i];
a[i] = a[0];
HeapAdjust(a, current, 0, i - 1);
}
}

int main()
{
/*  去重复
//int a[1000];
int k;
int n;
int size;
int find[10000];
int in_it[1000] = {0};
int index = 0;
//cout << "请输入要找的规模: ";
while (scanf("%d", &n) != EOF) {
//memset(in_it, 0, 100000*sizeof(int));
//cout << "请输入要找第几大的数字: ";

cin >> k;
size = k;
int *a = new int[k];
//cout << "输入找的序列: " << endl;
for (int i = 0; i < n; i++)
cin >> find[i];

//将不重复的数字放进堆中
bool ok = false;

int j = 0;

for (int i = 0; i < n && ok == false; i++)
{
bool init = false;
for (int m = 0; m < index; m++) {
if (in_it[m] == find[i])
init = true;
}
if (!init)
{
a[j] = find[i];
j++;
in_it[index] = find[i];
index++;

if (j == k)
ok = true;
}
}

//建堆
build_heap(a, size);

//开始寻找
for (int i = 0; i < n; i++)
{
bool init = false;
for (int j = 0; j < index; j++) {
if (in_it[j] == find[i])
init = true;
}
if (init)
continue;
else
{
if (find[i] > a[0])
{
a[0] = find[i];
build_heap(a, size);
}
}
}
HeapSort(a, size);
//cout << "前K大数字为:" << endl;
cout << a[0];
for (int i = 1; i < k; i++)
cout << " " << a[i];
cout << endl;
delete []a;
}
*/
//system("pause");

//不去重复
int k;
int n;
int size = 0;
int num;
//cout << "请输入要找的规模: ";
while (scanf("%d", &n) != EOF) {
//memset(in_it, 0, 100000*sizeof(int));
//cout << "请输入要找第几大的数字: ";
cin >> k;
size = 0;
int *a = new int[k];
//cout << "输入找的序列: " << endl;
for (int i = 0; i < n; i++)
{
cin >> num;
if (size < k)
{
a[size] = num;
size++;
continue;
}
if (i == k) build_heap(a, size);
if (num > a[0])
{
a[0] = num;
//build_heap(a, size);
HeapAdjust(a, num, 0, k - 1);
}
}

HeapSort(a, size);
//cout << "前K大数字为:" << endl;
cout << a[0];
for (int i = 1; i < k; i++)
cout << " " << a[i];
cout << endl;
delete []a;
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序 前K大数字
相关文章推荐