文件中海量数据的排序

文件中海量数据的排序

题目:

跟之前堆排序可以解决TopK问题一样,我们来看看归并排序会用来解决什么问题?

image-20240520225512621

思路:

我们说归并排序是外排序。其实就是将数据分成一个个小段,在内存中进行排序,再拿出内存,在外部,比如文件(磁盘中),进行归并排序。

其实就是数据量太大,无法直接通过内存来排序,我们将其平均切割成100份,1000份等等,比如将其切割成原数据切割成100份,每份拿出来就可以放到内存中去排序,排完之后放到一个个小文件中。

这样就会有100个小文件,这100个小文件里面都是排序好的数据,然后让文件去归并,让上一个文件和下一个文件中的数据去归并,最终实现的就是全部数据都放在一个文件里,并且是有序的。

文件的合并思路如下图所示

image-20240520233956417

文件归并的过程就是在文件中进行的,就是在磁盘上进行的。这就是外排序

image-20240521111447944

具体的归并思路:

就是让两个文件归并后的文件跟下一个文件接着归并。

image-20240521114326528

让file1 指向mfile文件,file2指向下一个文件,继续归并file1 和 file2文件,生成mfile文件

image-20240521114307224

然后就一直循环,直至mfile文件和第 n 个文件归并后。就结束。

代码实现:

void MergeFile(const char* file1, const char* file2, const char* mfile)
{// 打开file1 文件FILE* fout1 = fopen(file1, "r");if (fout1 == NULL){perror("MergeFile():fopen:fout1");exit(-1);}// 打开file2文件FILE* fout2 = fopen(file2, "r");if (fout2 == NULL){perror("MergeFile():fopen:fout2");exit(-1);}// 打开mfile文件,准备写入。FILE* fin = fopen(mfile, "w");if (fin == NULL){perror("MergeFile():fopen:fin");exit(-1);}// 将file1 和 file2的数据读出来,归并到mfile文件中int num1, num2;int ret1 = fscanf(fout1, "%d\n", &num1);int ret2 = fscanf(fout2, "%d\n", &num2);while (ret1 != EOF && ret2 != EOF) // 通过fscanf的返回值来判断是否有文件读取完毕{// 判断num1 和 num2 谁大谁小if (num1 < num2){fprintf(fin, "%d\n", num1); // 小的数据放到fin指向的文件ret1 = fscanf(fout1, "%d\n", &num1);// 这一步是为了让文件指针++ 读取下一个数据}else{fprintf(fin, "%d\n", num2);ret2 = fscanf(fout2, "%d\n", &num2);}}// 走到这里,有可能是fout1 或者是 fout2 文件先读取完// 要把剩下的进行处理while (ret1 != EOF){fprintf(fin, "%d\n", num1);ret1 = fscanf(fout1, "%d\n", &num1);}while (ret2 != EOF){fprintf(fin, "%d\n", num2);ret2 = fscanf(fout2, "%d\n", &num2);}// 关闭文件fclose(fout1);fclose(fout2);fclose(fin);
}void MergeSortFile(const char* file)
{// 读取传进来的file文件FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen:fout");exit(-1);}// 读取文件中的数据 ,将其分割成多组,在内存中进行排序,再放入对应文件中int n = 10; // 将文件中的数据切割成10个一组int num = 0;int* a = (int*)malloc(sizeof(int) * n); // 用于在内存中进行排序的数组int i = 0;int filei = 1; // 每组数据所存放的文件的下标char subfile[20]; // 用于存放各组数据文件的文件while (fscanf(fout, "%d\n", &num) != EOF) // 从文件中读取数据,写到num中 [读取失败返回EOF]{// 将读出来的数据放到一个数组中if (i < n - 1) // 只读前n - 1个到数组中 第n个在else中处理{a[i++] = num;}else{// 走进循环,fscanf还是读了一个数据到num上,要记得处理a[i] = num;// 走到这里,说明已经把文件中的数据全部读取到数组a中// 对其进行快排QuickSort(a, 0, n - 1);// n - 1是最后一个元素的下标// 排序完之后,我们将数据放回到文件中,这里我们选择每一组数据都放进一个文件中sprintf(subfile, "sub\\sub_sort%d.txt", filei++); // 创建各个文件的名字FILE* fin = fopen(subfile, "w"); // 打开subfile所记载的文件名,如果没有,由于是w形式 会自动创建一个if (fin == NULL){perror("fopen:fin");exit(-1);}// 往文件里写,我们排好序的数组for (int j = 0; j < n; j++){fprintf(fin, "%d\n", a[j]);}fclose(fin);i = 0; // 重置i}}// 现在文件中的数据, 被我们分成了一组组个数为n的有序数据,并放在了对应的文件中// 我们对这个文件,进行归并排序。  也就是在磁盘上进行文件内数据的归并,是外排序char mfile[100] = "12";char file1[100] = "sub\\sub_sort1.txt";char file2[100];char subsortfile[100] = "subsortfile\\12";  // 将归并后的mfile子文件都放到subsortfile文件中for (int i = 2; i <= n; i++){sprintf(file2, "sub\\sub_sort%d.txt", i);// 读取file1 和 file2的数据  归并到subsortfile文件的mfile子文件中MergeFile(file1, file2, subsortfile);// 更新file1指向的文件名strcpy(file1, subsortfile);// 更新mfilesprintf(mfile, "%s%d", mfile, i + 1);// 更新subsortfile的mfile子文件名sprintf(subsortfile, "subsortfile\\%s", mfile);}fclose(fout);
}

测试效果如下:

Sort是原数据存放的地方,我们这里只放了小数据,便于我们调试。

image-20240521134218393

sub文件中:

image-20240521134237892

subsortfile文件中:

image-20240521134311397

最终的12345678910就是所有文件归并后的结果。

将一开始的Sort文件内的数据,有序的存放在1234568910这个文件中

image-20240524121012351

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/839609.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux001】centos常用命令总结总结(已更新)

1.熟悉、梳理、总结下centos知识体系。 2.Linux相关知识&#xff0c;在日常开发中必不可少&#xff0c;如一些必知必会的常用命令&#xff0c;如环境搭建、应用部署等。同时&#xff0c;也要谨慎使用一些命令&#xff0c;如rm -rf&#xff0c;防止一些生产事故的发生。 3.欢迎点…

Mysql8.0离线安装 centos

Mysql8.0离线安装 centos 上传mysql安装包并解压 tar xvf mysql-8.0.37-1.el7.x86_64.rpm-bundle.tar运行安装对应的rpm包&#xff0c;按照一下顺序 rpm -ivh mysql-community-common-8.0.37-1.el7.x86_64.rpm rpm -ivh mysql-community-client-plugins-8.0.37-1.el7.x86_64.rp…

预约直播丨ETLCloud训练营:ETL中多流数据合并与运算专题

在大数据处理领域&#xff0c;一个至关重要的步骤是对多源数据流进行汇聚与融合&#xff0c;进而开展深度处理与剖析。此操作对于构建高效数据仓库、实现数据动态变化的实时洞察&#xff0c;以及驾驭复杂事件流的处理机制尤为关键。过程涉及从多样化的数据源中抽取信息&#xf…

Spring Boot 3.x使用knife4j

Spring Boot 3.x使用knife4j 1.添加knife4j依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version> </dependency>2.在…

【Unity Shader入门精要 第9章】更复杂的光照(四)

1. 透明度测试物体的阴影 对于物体有片元丢弃的情况&#xff0c;比如透明度测试或者后边会讲到的消融效果&#xff0c;使用默认的 ShadowCaster Pass 会产生问题&#xff0c;这是因为该Pass在生成阴影映射纹理时&#xff0c;没有考虑被丢弃的片元&#xff0c;而是使用完整的模…

建投数据收获客户感谢信

建投数据自2021年提出“以数据为核心的智能科技服务商”&#xff0c;并一直在为“成为国内领先的数字化转型合作伙伴”而努力&#xff0c;在赋能行业客户创造更大价值的同时&#xff0c;也陆续收到来自客户的肯定。 建投数据始终践行“成就客户&#xff0c;创新为要&#xff0…

【网络协议】【OSI】一次HTTP请求OSI工作过程详细解析

目录 1. 一次HTTP请求OSI工作过程 1.1 应用层&#xff08;第7层&#xff09; 1.2 表示层&#xff08;第6层&#xff09; 1.3 会话层&#xff08;第5层&#xff09; 1.4 传输层&#xff08;第4层&#xff09; 1.5 网络层&#xff08;第3层&#xff09; 1.6 数据链路层&am…

【vue部署】Apache部署vue项目

Apache部署vue项目 Apache 下载安装(windows)1. 下载2. 安装3. 启动服务 vue 部署配置1. 基础配置2. 解决页面刷新问题 Apache 下载安装(windows) 1. 下载 Apache 2.4.59 下载地址&#xff1a;httpd-2.4.59-240404-win64-VS17.zip Visual C Redistributable for Visual Studi…

AWS EC2 连接 AWS RDS(Mysql)

1 创建RDS数据库 点击创建数据库 引擎选项 模板 设置 连接 2 EC2连接Mysql $ sudo yum list mariadb* Installed Packages mariadb-connector-c.x86_64 3.1.13-1.amzn2023.0.3 amazonl…

TikTok矩阵管理系统:品牌增长的新引擎

随着社交媒体的快速发展&#xff0c;TikTok已成为全球最受欢迎的短视频平台之一。品牌和企业纷纷涌入这个平台&#xff0c;寻求新的增长机会。然而&#xff0c;随着内容的激增和用户群体的多样化&#xff0c;管理TikTok账号变得越来越复杂。这时&#xff0c;TikTok矩阵管理系统…

使用第三方的PyCharm开发工具

目录 PyCharm下载 PyCharm安装 运行PyCharm 创建工程目录 编写“hello world”程序 在同一个工程下创建多个程序文件 运行程序的多种方法 保存程序 关闭程序或工程 删除程序 打开最近的工程 调试断点 熟悉PyCharm开发环境 设置Python解析器 输出彩色控制台文字及…

50道题目!Python、SQL数据库、AB测试、业务分析、机器学习都在这里了!

介绍 每日一题系列已经更新了50道题目啦&#xff01; 题目难度为初级到中级&#xff0c;涵盖了Python、SQL数据库、AB测试、业务分析、机器学习五大主题&#xff0c;适合初学者和有一定基础的朋友。 原文链接: 50道题目&#xff01;Python、SQL数据库、AB测试、业务分析、机器…

pycharm 关闭项目卡死

PyCharm2023.3.4 关闭一直卡在 closing projects 解决办法&#xff1a; 打开PyCharm&#xff0c; 选择 Help -> Find Action -> 输入 Registry -> 禁用ide.await.scope.completion

10G SFP双口万兆以太网控制器,高速光口网络接口卡

2-Port 10G SFP NIC 是一款高速网 络接口卡&#xff0c;采用了 PCI Express 3.0 x8 接口&#xff0c;支持双 端口万兆以太网&#xff0c;具有高性能、高可靠性、低功耗等 优点&#xff0c;是数据中心、云计算、虚拟化等领域的理想选 择。 支持多种网络协议&#xff0c;如 …

【加密与解密(第四版)】第十六章笔记

第十六章 脱壳技术 16.1 基础知识 壳的加载过程&#xff1a;保存入口参数、获取壳本身需要使用的API地址、解密原程序各个区块的数据、IAT的初始化、重定位项的处理、HOOK API、跳转到程序原入口点 手动脱壳步骤&#xff1a;查找真正的入口点、抓取内存映像文件、重建PE文件&…

深度学习之基于Pytorch框架新冠肺炎CT图像分类

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着新冠肺炎&#xff08;COVID-19&#xff09;的全球爆发&#xff0c;快速、准确地诊断疾病成…

Python筑基之旅-MySQL数据库(二)

目录 一、第三方库 1、mysql-connector-python 1-1、由来 1-2、优缺点 1-2-1、优点 1-2-1-1、官方支持 1-2-1-2、纯Python实现 1-2-1-3、全面支持 1-2-1-4、兼容性 1-2-1-5、易于使用 1-2-2、缺点 1-2-2-1、性能 1-2-2-2、安装 1-2-2-3、社区支持 1-2-2-4、扩…

1020. 飞地的数量

1020. 飞地的数量 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_1020飞地的数量_dfs_定义方向_1020飞地的数量_bfs_定义方向 错误经验吸取 原题链接&#xff1a; 1020. 飞地的数量 https://leetcode.cn/problems/number-of-enclaves/…

十年磨一剑“2024成都电子信息展会”推动电子产业全球发展

2024成都电子展&#xff0c;招商工作已接近尾声&#xff0c;这场盛大的展会不仅是电子信息行业的一次盛会&#xff0c;更是中国西部电子信息产业发展的重要里程碑。自2013年起&#xff0c;中国&#xff08;西部&#xff09;电子信息博览会便选择成都作为其永久的举办地&#xf…

windows系统jupyter lab安装和配置:本地开发、探索大模型的利器

前言 在安装好anaconda之后&#xff0c;系统默认就安装好了一个jupyter notebook的工具&#xff0c;该工具可以在网页端运行&#xff0c;类似这样&#xff1a; 提供了一个按行运行的python运行环境&#xff0c;每一步的输出都可以打印到界面&#xff0c;对于我们初学python&am…