查找前k个最小值最直接的方式是遍历输入数组k遍,每次找出剩下输入中的最小值,每次查找过程中采用交换的策略,这样程序运行结束原数组的前k个数就是按顺序排列的前k个最小数,第二种思路是维护一个具有k个元素的查找树(初始化为输入数组的前k个数),对输入数组的后续每个元素a,将其与查找树的最大数b比较,如果a>=b,则什么也不做,如果a < b,则将b删除,再将a插入到查找树中,如此即可在O(n+klogn)时间内找到输入数组中的前k个最小值。第三种思路是在原数组上运行k遍初始化最小堆算法,第四种思路,如果输入是整数,则可以使用位图数据结构。下面是第二种思路的实现:
#include "stdafx.h"
#include <set>
#include <iostream>
using namespace std;
bool find_min_k(int input[],int result[],int input_count,int output_count)
{
if(input_count < output_count) return false;
set<int> s;
for (int i = 0; i < output_count; ++i)
{
s.insert(input[i]);
}
for (int i = output_count; i < input_count; ++i)
{
set<int>::iterator tempIt = --s.end();
if(input[i] < *tempIt)
{
s.erase(tempIt);
s.insert(input[i]);
}
}
int i = 0;
for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
{
result[i++] = *it;
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int myarray[] = {10,6,15,4,8,1,17,14,5,13,7,11,9,12,16};
int m = 15;
int n = 7;
int *result = new int[n];
if(find_min_k(myarray,result,m,n))
{
for (int i = 0; i < n; ++i)
{
cout<<result[i]<<endl;
}
}
return 0;
}
原文地址:http://blog.csdn.net/liao_jian/article/details/44405939