当前位置:   article > 正文

多路归并 外排序 大文件排序 海量数据处理_归并排序给大量数据怎么排序

归并排序给大量数据怎么排序

//多路归并外排序的实现
//将一个保存在磁盘上的文件内的数据进行排序
//基本思路是:设文件共有m*n条记录, 内存中每次可以对m条记录进行排序
//则排序过程分两步:
//第一步:从磁盘中读入m条记录到内存; 在内存排序; 将排好序的数据写入新文件; 
//         重复上述过程n次 共生成n个新文件

//第二步:分配一个文件指针数组 包含n个文件指针,分别指向n个新文件;
//   分配一个整数数组 大小为n 分别顺序读取各个文件的数据
//   分配一个布尔数组 大小为n 指示各个文件是否读完
//   将读入的整数数组中最小的值写入外存 并继续往后读取对应的文件 然后重复这一步 直到所有的文件都读完

这种算法思想常用于大文件排序,文件大小超出内存容量,可以每次读取内存容量的数据进行内存排序,然后进行归并

采用类似思想还可以解决很多海量数据处理的问题,当内存容量不足以一次处理时,通常都是先将大文件分为小文件,然后分而治之


关键程序段:

第一步

  1. while(1) {
  2. /*将数据读入内存,一次存满一数组*/
  3. while(i!=mount && (fscanf(in,"%d",&a[i])!=EOF))i++;
  4. /*内存内排序*/
  5. qsort(a, 0, i-1);
  6. /*将内存中排好的数据写到磁盘*/
  7. while(j!=i)fprintf(out, "%d ",a[j++]);
  8. if(i!=mount) break;
  9. }

第二步

  1. for(k=0;k<file_count;k++) {
  2. /*打开所有k个文件*/
  3. files[k] = fopen(tf_name,"r");
  4. /*让一个k大的数组依次指向每个文件,并用一个k大的bool数组指示此文件有没有读完*/
  5. if (fscanf(files[k], "%d ", &b[k]) == EOF) b_tag[k]=false;
  6. }
  7. while (true) {
  8. min = b[0];
  9. min_p = 0;
  10. /*在k个文件的“当前数据”中找最小的*/
  11. for (k=0;k<file_count;k++) {
  12. if (b_tag[k]&&b[k]<min) {
  13. min=b[k];
  14. min_p = k;
  15. }
  16. }
  17. if (min_p == 0 && !b_tag[0]) break;
  18. /*写入文件*/
  19. fprintf(out, "%d ", min);
  20. /*然后对应的文件中的指针后移*/
  21. if (fscanf(files[min_p], "%d ", &b[min_p])==EOF){
  22. b_tag[min_p] = false;
  23. }
  24. }

全部源代码


  1. ///
  2. #include <iostream>
  3. using namespace std;
  4. class ExternSort
  5. {
  6. public:
  7. ExternSort(const char *in, const char *out, int m)
  8. {
  9. file_in = new char[strlen(in)+1];
  10. strcpy(file_in, in);
  11. file_out = new char[strlen(out)+1];
  12. strcpy(file_out, out);
  13. mount = m;
  14. }
  15. ~ExternSort()
  16. {
  17. delete []file_in;
  18. delete []file_out;
  19. }
  20. int sort()
  21. {
  22. FILE *in = NULL;
  23. FILE *out = NULL;
  24. FILE **files = NULL;
  25. if (!(in = fopen(file_in, "r"))){
  26. cout<<"open file error"<<endl;
  27. }
  28. int file_count = 0;
  29. char tf_name[10];
  30. int a[mount], k;
  31. int *b = NULL;
  32. bool *b_tag = NULL;
  33. int min, min_p;
  34. while(1) {
  35. int i=0, j=0;
  36. while(i!=mount && (fscanf(in,"%d",&a[i])!=EOF))i++;
  37. qsort(a, 0, i-1);
  38. sprintf(tf_name,"%d",file_count++);
  39. out = fopen(tf_name, "w");
  40. while(j!=i)fprintf(out, "%d ",a[j++]);
  41. fclose(out);
  42. if(i!=mount) break;
  43. }
  44. out = NULL;
  45. files = new FILE*[file_count];
  46. b = new int[file_count];
  47. b_tag = new bool[file_count];
  48. memset(files, 0, file_count);
  49. memset(b, 0, file_count);
  50. memset(b_tag, true, file_count);
  51. for(k=0;k<file_count;k++) {
  52. sprintf(tf_name, "%d", k);
  53. files[k] = fopen(tf_name,"r");
  54. if (fscanf(files[k], "%d ", &b[k]) == EOF) b_tag[k]=false;
  55. }
  56. out = fopen(file_out, "a");
  57. while (true) {
  58. min = b[0];
  59. min_p = 0;
  60. for (k=0;k<file_count;k++) {
  61. if (b_tag[k]&&b[k]<min) {
  62. min=b[k];
  63. min_p = k;
  64. }
  65. }
  66. if (min_p == 0 && !b_tag[0]) break;
  67. fprintf(out, "%d ", min);
  68. if (fscanf(files[min_p], "%d ", &b[min_p])==EOF){
  69. b_tag[min_p] = false;
  70. }
  71. }
  72. fclose(in);
  73. fclose(out);
  74. for(k=0;k<file_count;k++) fclose(files[k]);
  75. for(k=0;k<file_count;k++) {
  76. sprintf(tf_name, "%d", k);
  77. remove(tf_name);
  78. }
  79. delete[] b;
  80. delete[] b_tag;
  81. delete[] files;
  82. }
  83. private:
  84. char *file_in;
  85. char *file_out;
  86. int mount;
  87. void qsort(int *a, int s, int e)
  88. {
  89. int i=s, j=e;
  90. int temp = a[i];
  91. if (i<j) {
  92. while (i<j) {
  93. while (i<j&&a[j]>=temp)j--;
  94. a[i] = a[j];
  95. while (i<j&&a[i]<=temp)i++;
  96. a[j] = a[i];
  97. }
  98. a[i] = temp;
  99. qsort(a, s, i-1);
  100. qsort(a, i+1, e);
  101. }
  102. }
  103. };
  104. int main(int argc, char *args[])
  105. {
  106. FILE *f = fopen("in", "w");
  107. for(unsigned int i=0; i<10000000;i++) fprintf(f, "%d ", rand()%10000);
  108. fclose(f);
  109. ExternSort e = ExternSort("in", "out",100000 );
  110. e.sort();
  111. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/830065
推荐阅读
相关标签
  

闽ICP备14008679号