算法学习(七)有内存限制的海量数据排序

磁盘文件排序

问题描述:
输入:给定一个文件,里面最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数),且其中每个数都小于等于n,n = 10^7。
输出:得到按从小到大升序排列的包含所有输入的整数的列表。
条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在五分钟以下,10秒为最佳结果。
分析:
首先注意的是它的内存要求,基本上否决了大多数的排序算法。
文件里面的数据是不重复的,这个很关键,因为下面的方案前提就是数据不重复。

位图方案

以位为最小单位,对应位为1,代表位数值,可以用20位长的字符串来表示一个所有元素都小于20的简单的非负数集合,边框用如下字符串来表示集合{1,2,3,5,8,13}:
01110100100001000000
对应位置则置1,没用对应数的位置则置0,开始扳手指头数数吧。我们可以采用一个具有1000万个位的字符串来表示这个文件,其中,当整数i在文件中时,第i位为1。
第一步,所有位置0,将集合初始化。
第二步,通过读入文件中的每个整数来建立集合,将对应的位都置1.
第三步,检验每一位,如果该位为1,就输出对应的整数。
这里不得不提一下c++库中的一个容器bitset,发现这个在处理位的时候简直牛,先来瞅瞅。

#include <iostream>
#include <bitset>
using namespace std;
int main()
{
    const int max = 20;
    int arr[10] = {
  2,9,3,5,4,0,18,11,12,15};
    bitset<max> bit_map;  //一种类模板,放入长度,定义了一个max位,每位都为0
    bit_map.reset();  //所有位置0
    int i;
    for(i = 0;i< 10;i++)
    {
        bit_map.set(arr[i]);  //将对应位置1
    }
    for(i = 0;i< max;i++)
    {
        if(bit_map.test(i))  //判断第i位,如果为1,返回true
            cout << i << " ";
    }
    cout << endl;
    return 0;
}

再加上文件操作,就是针对海量数据排序。

#include <iostream>
#include <bitset>
#include <assert.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

const int MAX = 5000000;
int main()
{
    clock_t begin = clock();
    bitset<MAX> bit_map;
    bit_map.reset();

    FILE * fp_unsort_file = fopen("data.txt","r");
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值