当前位置: 首页 > news >正文

(排序10)归并排序的外排序应用(文件排序)

TIPS

  1. 在一些文件操作函数当中,fputc与fgetc这两个函数都是针对字符的,如果说你需要往文件里面去放入整形啊等等,不是字符的类型,这时候就用fprintf,fscanf在参数里面数据类型控制一下就可以。但是话说回来,数据文件的话分为文本文件与二进制文件,文件里面的信息唯有二进制信息或者字符ASCII码,然后当你点开文件解析出来的时候都是强制解析成字符的。
  2. 对于C文件操作我还是想再补充几点:首先对于这两个函数fgetc,fputc他们针对的都是字符,比如说可以从内存当中往文件(以文件作为外部输出设备的例子)当中去放字符,也可以从文件当中往内存里面读出来一个字符,但无论如何,他针对的数据类型只有字符;
  3. 然后对于这两个函数fgets与fputs,他们针对的是一行字符串的输入与输出,这边尤其要注意在文件当中每一行字符串的末尾都是默认带有一个换行符\n,这个换行符的话也是需要计数的(参照fgets的参数),并且如果说条件允许也是会被拷贝到内存当中,并且文件指针一旦碰到了这个换行符,它也会换行;
  4. 对于fprintf, fscanf这两个函数来说的话,他们针对的是格式化字符串的输入输出,并且最大的优势与亮点就是说他们的类型很是自由,比如说我想往文件里面放入一个数字,然后我假设要从文件里面过一会儿读出这个数字重新到内存里面来,这时候就不好用fgetc,fputc。因为那两个的话是针对于字符的,这时候就用fprintf,fscanf加%d格式化非常nice。
  5. 最后对于这两个函数sscanf,sprintf来说,这两个函数的功能分别是从字符串当中去抠东西下来放到变量当中,粘连一些东西或者自己添油加醋一些合成一个新字符串。
    在这里插入图片描述
    在这里插入图片描述

归并排序的外排序(文件排序)

  1. 文件排序的话,主要是针对大文件,如果你针对小文件的话就没有意义了。但这边总不能真正的给500个g的数据吧,我们这边就模拟一下
  2. 现在假设有海量的排序数据,那么他这个数据肯定是在文件当中,在磁盘当中,因为磁盘相对于内存大太多了。然后如果我们要对这些数据进行排序的话,不能把他们全部一下子加载到内存里面,因为内存没有这么大
  3. 这时候我们只能用归并排序的思想,归并排序就是说比如说有两段有序的数据,这一段是有序的,那一段也是有序的。然后我们就开一个新的地方,然后每次取小的下来给他放到新的地方里面,就这样把两个有序区间给他归并到一个有序区间。好好去想一想归并的四个生动表述过程。
    在这里插入图片描述
  4. 归并排序的话,既可以把它看成内排序,它也可以搞成外排序。但无论如何他都具有O(N)的空间复杂度,所以说是蛮消耗存储空间的。所以说在内排序当中,它跟快速排序相比的话逊一点,内排序综合快排取胜
  5. 然后现在当数据在文件当中的话,前面的那些快的排序:堆排啊,快排啊都不好弄了,堆排与快排的话都需要随机访问这个大前提,像数组的话很友好,能够支持随机访问,但文件的话就不能进行随机访问了,就算你可以去移动文件指针那也非常非常慢,磁盘的速度相比较于内存而言慢太多了,差异在几百几千倍。所以外排用归并。
  6. 但在归并的过程当中,如果说你用递归的思想,比如说把十个g的文件给他,先分成5个g,5个g,那我如果想要归并的话,首先得确保这两个五个g的文件数据是有序的。那该怎么确保呢?是不是相当于又要继续划分下去,那这样划分下去,不是要划分死了吗?而且我们真正在归并的时候,为了效率提高,我们一定要借助于内存,而不是全部在慢吞吞的磁盘里面。
  7. 所以总的思路就是这样:首先把大文件给他平均分割成N份,然后保证每一份的大小都可以加载到内存当中(我必须借助于内存,没办法,不然纯硬盘里面就慢到猴年马月了),然后因为我等会儿要依托这个每一份的划分出来的小文件为基准量不断向上归并,所以说前提是这些划分出来的小文件必须有序,由于他们现在倒是能够加载到内存里面,所以说先把他们读到内存里面用快速排序把他们先排成有序的
  8. 然后在内存里面给它全部把数据排成有序之后再写回小文件当中。那么这时我们就达到了文件中归并的先决条件。现在都是一个一个有序的小文件了。
  9. 首先就是对磁盘当中的海量数据不断的读,然后用一个变量去控制一下,比如说我现在假定每个小文件里面的数据个数是十个,那么在不断读取的过程当中,每读到十个的时候,然后此时此刻停顿一下,把这十个数据给他,在内存当中快速排序一下,并且给他去创建一个新的文件,并且把这十个在内存当中已经有序的数据给他读到那个文件里面去。当然里面有一些具体的细节的话,就去处理一下就可以,包括边界问题呀等等代码逻辑处理好就可以。
  10. 然后接下来就是文件之间的归并。这时候就肯定不能在内存当中了,因为内存里面已经放不下两个文件合起来这么一个数据量。因为归并排序的话,它的空间复杂度必须是O(N)。然后如果说两两一归并的话,有个很恶心的问题,就是取名字的问题。我们虽然采用非递归归并,但其实也可以不用去两两一归并,可以如下:
    在这里插入图片描述

实际代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ALL_NUMBER 10000
#define EVERY_NUMBER 1000
#define NAME_MAX 100
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
int GetMidNumi(int* arr, int left, int right)
{int mid = (left + right) / 2;if (arr[left] < arr[mid]){if (arr[left] > arr[right]){return left;}else{return arr[mid] < arr[right] ? mid : right;}}else{if (arr[right] > arr[left]){return left;}else{return arr[mid] > arr[right] ? mid : right;}}
}
void QuickSort(int* arr, int left, int  right)
{if (left >= right){return;}int begin = left;int end = right;int midi = GetMidNumi(arr, left, right);Swap(arr + left, arr + midi);int keyi = left;while (left < right){while (left < right && arr[right] >= arr[keyi]){right--;}while (left < right && arr[left] <= arr[keyi]){left++;}Swap(arr + left, arr + right);}Swap(arr + left, arr + keyi);keyi = left;QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}
void CreateNumber()
{srand((unsigned int)time(NULL));FILE* pf = fopen("number.txt", "w");if (pf == NULL){perror("fopen failed");return;}for (int i = 0; i < ALL_NUMBER; i++){int num = rand();fprintf(pf, "%d\n", num);}fclose(pf);pf = NULL;
}
void MergeSortFile(char* file1, char* file2, char* file)
{FILE* pf1 = fopen(file1, "r");if (pf1 == NULL){perror("fopen failed");return;}FILE* pf2 = fopen(file2, "r");if (pf2 == NULL){perror("fopen failed");return;}FILE* pf = fopen(file, "w");if (pf == NULL){perror("fopen failed");return;}int num1 = 0;int num2 = 0;int ret1 = fscanf(pf1, "%d", &num1);int ret2 = fscanf(pf2, "%d", &num2);while (ret1 != EOF && ret2 != EOF){if (num1 < num2){fprintf(pf, "%d\n", num1);ret1 = fscanf(pf1, "%d", &num1);}else{fprintf(pf, "%d\n", num2);ret2 = fscanf(pf2, "%d", &num2);}}while (ret1 != EOF){fprintf(pf, "%d\n", num1);ret1 = fscanf(pf1, "%d", &num1);}while (ret2 != EOF){fprintf(pf, "%d\n", num2);ret2 = fscanf(pf2, "%d", &num2);}fclose(pf1);fclose(pf2);fclose(pf);
}
void Cover(char* file1, char* file2)
{FILE* pf1 = fopen(file1, "r");if (pf1 == NULL){perror("fopen failed");return;}FILE* pf2 = fopen(file2, "w");if (pf2 == NULL){perror("fopen failed");return;}int num = 0;int res = 0;while (fscanf(pf1, "%d", &num) != EOF){fprintf(pf2, "%d\n", num);}fclose(pf1);fclose(pf2);
}
int main()
{CreateNumber();FILE* pf = fopen("number.txt", "r");if (pf == NULL){perror("fopen failed");return;}int arr[EVERY_NUMBER] = { 0 };char file1[NAME_MAX] = { 0 };char file2[NAME_MAX] = { 0 };char file[NAME_MAX] = { 0 };int res = 0;int i = 0;int count = 0;while ((res = fscanf(pf, "%d", &arr[i++])) != EOF){if (i == EVERY_NUMBER){count++;if (count == 1){sprintf(file1, "%d", count);}sprintf(file2, "%d", count);QuickSort(arr, 0, EVERY_NUMBER - 1);i = 0;FILE* _pf = fopen(file2, "w");if (_pf == NULL){perror("fopen failed");return 1;}for (int j = 0; j < EVERY_NUMBER; j++){fprintf(_pf, "%d\n", arr[j]);}fclose(_pf);if (count > 1){sprintf(file, "%s%s", file1, file2);MergeSortFile(file1, file2, file);strcpy(file1, file);}}}fclose(pf);Cover(file, "number.txt");return 0;
}

相关文章:

(排序10)归并排序的外排序应用(文件排序)

TIPS 在一些文件操作函数当中&#xff0c;fputc与fgetc这两个函数都是针对字符的&#xff0c;如果说你需要往文件里面去放入整形啊等等&#xff0c;不是字符的类型&#xff0c;这时候就用fprintf&#xff0c;fscanf在参数里面数据类型控制一下就可以。但是话说回来&#xff0c…...

浅谈根号分治与分块

文章目录 1. 根号分治哈希冲突 2. 线性分块引入教主的魔法[CQOI2011] 动态逆序对[国家集训队] 排队[HNOI2010] 弹飞绵羊蒲公英 1. 根号分治 哈希冲突 题目1 n n n 个数&#xff0c; m m m 次操作。操作 1 为修改某一个数的值&#xff0c;操作 2 为查询所有满足下标模 x x x …...

(OpenAI)ChatGPT注册登录常见问题错误代码及其解决方法

在使用 ChatGPT 的时候我们可能会碰到一些错误的代码&#xff0c;本文统一来介绍一下每一种错误以及解决方法。 错误代码1. 不能在当前国家使用 出现场景&#xff1a;一般在注册或登录的时候会出现。 原因&#xff1a;主要是ChatGPT检测到当前访问所在的地区不允许访问导致。 …...

MySQL主从复制、读写分离(MayCat2)实现数据同步

文章目录 1.MySQL主从复制原理。2.实现MySQL主从复制&#xff08;一主两从&#xff09;。3.基于MySQL一主两从配置&#xff0c;完成MySQL读写分离配置。&#xff08;MyCat2&#xff09; 1.MySQL主从复制原理。 MySQL主从复制是一个异步的复制过程&#xff0c;底层是基于Mysql数…...

Linux 云服务器好用吗?(解读Linux云服务器的特点优势)

​  如今&#xff0c;云计算越来越受欢迎&#xff0c;许多公司正在将业务转移到那里。企业向云过渡的主要原因是它提供的众多服务&#xff0c;包括安全和充足的存储、数据库、服务器和其他关键元素。 作为相对前|沿的技术之一&#xff0c;云建立在虚拟服务器上。Linux 服务器…...

研读Rust圣经解析——Rust learn-8(match,if-let简洁控制流,包管理)

研读Rust圣经解析——Rust learn-8&#xff08;match,if-let简洁控制流&#xff0c;包管理&#xff09; matchother和占位符_区别 easy matchenum matchno valuematch inner Option matchmore better way if-let整洁控制包管理模块(mod)拆分声明modpub公开use展开引用拆解模块结…...

G8期刊《全体育》期刊简介及投稿要求

G8期刊《全体育》期刊简介及投稿要求 《全体育》是由湖南体育产业集团有限公司主管、体坛传媒集团股份有限公司主办、中教体育 出版发行的体育综合性期刊。 主管&#xff1a;湖南体育产业集团有限公司 主办&#xff1a;体坛传媒集团股份有限公司 国内刊号&#xff1a;CN4…...

数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)

目录 层序遍历 思路图解 代码实现 二叉树遍历的应用 输出二叉树中的叶节点 代码实现 求二叉树的高度 思路图解 代码实现 二元运算表达式树及其遍历 由两种遍历序列确定二叉树 层序遍历 层序遍历可以通过一个队列来实现&#xff0c;其基本过程为&#xff1a; 先根…...

【Neo4j数据库】图数据库_Neo4j增加节点(关系)、查询、删除数据库等操作解析(Cypher语句)

【Neo4j数据库】图数据库_Neo4j增加节点&#xff08;关系&#xff09;、查询、删除操作解析&#xff08;Cypher语句&#xff09; 文章目录 【Neo4j数据库】图数据库_Neo4j增加节点&#xff08;关系&#xff09;、查询、删除操作解析&#xff08;Cypher语句&#xff09;1. 介绍2…...

Linux移动文件和文件夹(目录)命令

命令mv 英文move 翻译移动 mv命令可以移动文件或文件夹&#xff08;目录&#xff09;&#xff0c;也可以重命令&#xff08;覆盖&#xff09;文件。 1. 移动文件/重命名 单纯地移动某一个文件直接使用&#xff1a; mv <源文件名称/地址> <新文件名称/地址>这个方法…...

Pandas的应用-5

Pandas是一个强大的数据处理库&#xff0c;它提供了高性能、易于使用的数据结构和数据分析工具。本文将介绍Pandas常用的数据结构和常用的数据分析技术&#xff0c;包括DataFrame的应用、窗口计算、相关性判定、Index的应用、范围索引、分类索引、多级索引以及日期时间索引。 …...

java继承类怎么写

继承类是通过把父类的方法和属性继承到一个类中&#xff0c;而子类的方法和属性是子类自己定义的。 Java中有一个很重要的概念叫做继承&#xff0c;这也是 Java语言的精髓所在。Java语言提供了一种机制&#xff0c;叫做派生类。在 Java中&#xff0c;如果没有实现了某个派生类方…...

面向对象程序设计

OOP 【面向对象程序设计】&#xff08;OOP&#xff09;与【面向过程程序设计】在思维方式上存在着很大的差别。【面向过程程序设计】中&#xff0c;算法是第一位的&#xff0c;数据结构是第二位的&#xff0c;这就明确地表述了程序员的工作方式。首先要确定如何操作数据&#…...

Linux 用户身份切换(su,sudo)

文章目录 Linux 用户身份切换su使用案例 sudo使用案例 visudo与/etc/sudoers单一用户可使用root所有命令&#xff0c;与sudoers文件语法利用wheel用户组以免密码的功能处理visudo有限制的命令操作通过别名创建visudosudo的时间间隔问题sudo搭配su的使用方式 Linux 用户身份切换…...

求倒置数问题

文章目录 求倒置数程序设计程序分析求倒置数 【问题描述】数组A【0,…,n-1】是一个n个不同整数数构成的数组。如果i<j,但是A[i]〉A[j],则这对元素(A[i],A[j])被称为一个倒置(inversion)。设计一个O(nlogn)算法来计算数组中的倒置数量 【输入形式】输入两行,第一行…...

sed(学习)

1、清除环境变量 ​​​​​​profile~/.bash_profile sed -i s#export LD_LIBRARY_PATH.*##g $profile 2、设置环境变量(替换值) sed -i s#export LD_LIBRARY_PATH.*#export LD_LIBRARY_PATH/opt/testlinux/lib#g ~/.bash_profile 3、修改配置文件 sdk_dir/root/test log_dir/…...

B - GCD Subtraction

文章目录 AtCoder Regular Contest 159B - GCD Subtraction AtCoder Regular Contest 159 B - GCD Subtraction 问题&#xff1a;每次A,B都减去gcd(A,B)&#xff0c;求其中一个减到0至少需要多少次主要思路&#xff1a; 首先第一步应该想到每次减去的数&#xff0c;先减去的数…...

解决Failed to load ApplicationContext问题的思路

中文翻译&#xff1a; 加载ApplicationContext失败 第一步&#xff1a;首先检查测试类的注解 以及 依赖 SpringBootTest <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scop…...

基于CAMX大气臭氧来源解析模拟与臭氧成因分析实践技术应用

查看原文>>>基于CAMX大气臭氧来源解析模拟与臭氧成因分析实践技术应用 目录 专题一、大气臭氧污染来源及成因分析技术讲解&#xff1b;CAMx模式初识及臭氧来源解析模拟本地案例配置说明 专题二、CAMx模式编译安装及空气质量模拟案例配置 专题三、CAMx扩展和探测工…...

异常的讲解 (1)

目录 异常入门的案例 异常介绍 基本概念 异常的小结 常见的运行时异常 1.NullPointerException空指针异常 2.ArithmeticException数学运算异常 3.ArraylndexOutOfBoundsException数组下标越界异常 4.ClassCastException类型转换异常 5.NumberFormatException数字格式不…...

【亲测免费】 TC8协议一致性测试文档

TC8协议一致性测试文档 【下载地址】TC8协议一致性测试文档 本仓库提供了一个重要的资源文件&#xff0c;即**TC8协议一致性测试文档**。该文档详细描述了汽车以太网ECU&#xff08;电子控制单元&#xff09;在不同网络层的一致性测试规范。具体包括以下三个部分&#xff1a;1.…...

Cadence SPB17.4导入外部封装后,原理图封装属性不更新?一个属性编辑框解决你的困扰

Cadence SPB17.4原理图封装属性更新难题&#xff1a;从数据库到设计的完整解决方案 当你花费数小时将力创封装库成功导入Cadence PCB Editor后&#xff0c;满心欢喜地打开原理图进行DRC检查&#xff0c;却发现那些熟悉的"PCB Footprint Not Found"错误依然存在——这…...

OpenClaw 上下文瘦身:3 个实验

这篇不是讲“提示词怎么写得更优雅”。我只看一个更硬的问题&#xff1a;Agent 跑久以后&#xff0c;上下文到底是怎么胖起来的&#xff0c;哪一刀最值得先砍。实验脚本和结果都放在本地目录里&#xff0c;可以复跑。你大概见过这种故障&#xff1a; Agent 前 10 分钟很听话&am…...

如何用QKeyMapper实现Windows键鼠手柄自由映射:免费开源终极指南

如何用QKeyMapper实现Windows键鼠手柄自由映射&#xff1a;免费开源终极指南 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper&#xff0c;Qt开发Win10&Win11可用&#xff0c;不修改注册表、不需重新启动系统&#xff0c;可立即生效和停止。支持游戏手柄映射到键鼠&…...

多平台布局时代,店群账号高效管控之道

在电商行业持续精细化运营的当下&#xff0c;店群模式仍是商家拓宽渠道、分散风险、提升规模效应的主流选择。伴随抖店、拼多多、TikTok Shop、Temu、亚马逊等国内外平台规则趋严&#xff0c;多店铺账号管理已成为制约店群商家稳定经营的关键瓶颈。传统依赖人工登记、多设备登录…...

AI为编程赋能增效:从“古法编程”到氛围编程的范式革命

在人工智能技术飞速发展的今天&#xff0c;编程领域正经历着一场前所未有的范式革命。曾经&#xff0c;我们习惯于在编辑器中逐行敲击代码&#xff0c;为复杂的语法纠错而焦头烂额&#xff0c;那个需要死记硬背各种操作符与数据结构的“古法编程时代”正在悄然落幕。取而代之的…...

STM32F429三重ADC+DMA实战:从CubeMX配置到7.2MHz采样率代码调试全流程(避坑指南)

STM32F429三重ADCDMA极限采样实战&#xff1a;从CubeMX配置到7.2MHz数据采集全解析 在工业测量、医疗设备或高频信号分析领域&#xff0c;对高速数据采集的需求日益增长。当常规的单ADC方案无法满足采样率要求时&#xff0c;STM32F429的三重ADC交替采样模式配合DMA传输&#xf…...

单传感器肌电假肢:DTW算法实现92%识别准确率

1. 项目概述肌电假肢技术在过去几十年里取得了显著进展&#xff0c;但传统多传感器系统的高成本和复杂性仍然是阻碍其普及的主要障碍。作为一名从事生物医学工程研究多年的从业者&#xff0c;我一直在寻找更经济高效的解决方案。这项研究提出了一种创新方法&#xff1a;仅使用单…...

自动驾驶安全基石:从ODD到ODC的设计原则与工程实践

1. 自动驾驶安全的底层逻辑&#xff1a;为什么需要ODD与ODC&#xff1f; 十年前我第一次接触自动驾驶系统时&#xff0c;工程师们最常讨论的是传感器精度和算法性能。直到参与某L3级高速领航项目后&#xff0c;我才真正理解&#xff1a;定义"在什么条件下能安全运行"…...

软考高级之系统架构师之系统安全性和保密性设计(二)

认证 PKI/CA 参考PKI/CA体系介绍。 Kerberos Kerberos是一种网络认证协议&#xff0c;其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证&#xff0c;无需基于主机地址的信任&#xff0c;不要求网络上所有主…...