例如:假设要对8亿个正整数进行排序(000000000-999999999),该如何操作?

分析:首先,确认这些数是不是不重复的,这点很重要,8亿个9整数占用内存很庞大,用计算机直接一次性进行处理显然不现实,800,000,000*4Byte=3.0G。为此可以利用Bloom Filter建立N个哈希函数的映射集;或者使用导入数据库的方法;还可以使用bit位的方法......

1、分段排序

由于这8亿个数是在数据段000000000-999999999内的,因此可能的数一共有10亿个,3.8G空间完全可以足够,为此可以将该数据段分为000000000-099999999、100000000-199999999、......、900000000-999999999共10段,对8亿个整数依次搜索位于每一段的数并提取到内存进行排序,然后输出,每段为372M,完全在Win32的处理能力内,如是进行10次,并将结果连接起来即可。

由于分段的原因,导致要对许多数字进行多次搜索,例如,如果按分段从前往后的顺序依次搜索读入内存的话,位于最后一段内(即900000000-999999999)的数要被搜索10次,往前依次类推,因此如果该数均匀分布的话,平均要被搜索5.5次,严重影响速度和效率。

2、导入数据库

可以利用现成的数据库进行数据的导入,并进行排序,该方法操作简单,但是要用到数据库设备,成本增加。

3、bit位方法

由于这8亿个数位于000000000-999999999范围内,为此可以建立一个10位的二进制数组或空间,对应位置的下标分别为000000000-999999999,则占用内存约为120M,完全位于系统处理能力内。为此,先将10亿位全部置为0,依次读入8亿个数,将该位置的bit值置为1,直至结束,则得到一个8亿位置为1的10亿数组。将该数组中bit位为1的下标值依次输出到文件,即得到排序结果。该方法,占用内存小,读取次数少,处理速度相对快。

可以将数据文件分别读入,读入一段的代码如下:

 

   
   
   
   
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.  
  6. using namespace std;  
  7.  
  8. int CountLines(char *filename)//获取文件的行数  
  9. {  
  10.     ifstream ReadFile;  
  11.     int n = 0;  
  12.     string temp;  
  13.     ReadFiles.open(filename.ios::in);//ios::in表示以只读的方式读入读取文件  
  14.     if(ReadFile.fail())  
  15.     {  
  16.         return 0;  
  17.     }//if  
  18.     else{  
  19.         while(getline(ReadFile,temp))  
  20.         {  
  21.             n++;  
  22.         }//while  
  23.         return n;  
  24.     }//else  
  25.     ReadFile.close();  
  26. }//CountLines  
  27.  
  28. void input(){  
  29.     ifstream file;  
  30.     int LINES;  
  31.     int *tc = new int[LINES];  
  32.     bitset <1000000000> address;  
  33.     cout<<"请输入要打开的文件名:"<
  34.     cin>>filename;  
  35.     file.open(filename,ios::in);  
  36.     if(file.fail()){  
  37.         cout<<"文件不存在!"<
  38.         file.close();  
  39.         cin.get();  
  40.     }else{  
  41.         LINES=CoutnLines(filename);  
  42.         int *tc = new int[LINES];  
  43.         int i = 0;  
  44.         while(!file.eof()){//读取数据到数组  
  45.             file>>tc[i];  
  46.             address.set(tc[i]);  
  47.             ++i;  
  48.         }  
  49.         file.close();  
  50.     }  
  51. }  

依次将文件读入后,最后得到结果,一次性输出:

 

   
   
   
   
  1. ofstream in;  
  2. in.open("result.txt",ios::trunc);//ios::trunc表示在打开文件前将文件清空,不存在则创建之  
  3.  
  4. size_t m = address.size();  
  5. for(int j = 0;j! = m;++j)  
  6. if(address.test(j))  
  7.     in<"\n";  
  8. in.close(); 

排序结束!恳请各位大牛小牛各种牛轻拍指正......