您的位置:首页 > 其它

上亿个数据保存在硬盘中,找出最大的N个。

2013-01-28 22:51 190 查看
(1)先选N个元素组成一个小根堆,然后遍历剩下的数据,如果第i个元素M大于小根堆的根结点,就删除这个根结点,并将元素M插入这个小根椎,最后,小根堆中的元素就是最大的N个元素。

(2)只要开辟一个稍微大一点的缓冲区存放大于某选定值的数据即可,当缓冲满时,刷新选定值为缓冲区的第n大值,即可(同时清理缓存区)。

(3)用O(M)的时间找出第N大元素,然后再遍历一边找出比这个数大的N个数即可,理论复杂度O(M),不过N较小的时候可能是1L的更有效率

解法(1)及时考虑数据不可能全部加入内存,也可以在内存中开辟一个缓冲区,每次读取磁盘中的K(K<M)个数据进入内存,然后在一个一个的与堆进行比较。当缓冲区空时,则再读入K个数据。总之减少IO读取次数也是一个高效的重要方面。

解法(2)如何选定值

解法(3)是一个方向,可以使用快速排序算法,选择递归搜索的方向,理论上可以达到O(M),但找第N大元素时,如何不需要把所有数据读入内存呢?

给出方法(1)的一个算法,使用set,有重复数据也可以用multiset,set使用的是红黑树,可以改善插入、删除的效率

int main(int argc, char* argv[])
{
set<int> set_MAX_N;
ifstream inFile("test.txt");
int nTemp;
while(inFile >>nTemp)
{
set_MAX_N.insert(nTemp);
if(set_MAX_N.size() > N)
{
set_MAX_N.erase(set_MAX_N.begin());
}
}
for(set<int>::iterator it = set_MAX_N.begin();it != set_MAX_N.end(); it ++)
cout<< *it <<endl;
while(1);
return 0;
}


转自:http://bbs.csdn.net/topics/340000263
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐