外排序之文件归并排序实现

外排序介绍

外排序是指能够处理极大量数据的排序算法。通常来说,外排序处理的数据不能一次装入内存,只能放在读写较慢的外存储器(通常是硬盘)上。外排序通常采用的是⼀种“排序-归并”的策略。在排序阶段,先读入能放在内存中的数据量,将其排序输出到⼀个临时文件,依此进行,将待排序数据组织为多个有序的临时文件。然后在归并阶段将这些临时文件组合为⼀个大的有序文件,也即排序结果。
跟外排序对应的就是内排序,之前常见的排序,都是内排序,这些排序思想适应的是数据在内存中,支持随机访问。归并排序的思想不需要随机访问数据,只需要依次按序列读取数据,所以归并排序既是⼀个内排序,也是⼀个外排序。

创建随机数据文件的代码

void CreatData()
{int n = 100000;srand((unsigned int)time(NULL));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("foprn fail!");return;}for (int i = 0; i < n; i++){int x = rand() % n + 1;fprintf(fin, "%d\n", x);}fclose(fin);
}

在这里插入图片描述

文件归并排序思路分析

  1. 读取n个值排序后写到file1,再读取n个值排序后写到file2
  2. file1file2利⽤归并排序的思想,依次读取比较,取小的尾插到mfilemfile归并为⼀个有序文件
  3. file1file2删掉,mfile重命名为file1
  4. 再次读取n个数据排序后写到file2
  5. 继续⾛file1file2归并,重复步骤2,直到文件中无法读出数据。最后归并出的有序数据放到了file1

在这里插入图片描述

文件归并排序代码实现

  • 创建随机数据文件的代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>void CreatData()
{int n = 100000;srand((unsigned int)time(NULL));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("foprn fail!");return;}for (int i = 0; i < n; i++){int x = rand()+i;fprintf(fin, "%d\n", x);}fclose(fin);
}
  • 取n个数据放入file1中,并进行排序
int compare(const void* a, const void* b)
{return (*(int*)a - *(int*)b);
}int ReadNDataSortToFile(FILE* fout, int n, const char* file1)
{int x = 0;int* a = (int*)malloc(sizeof(int) * n);if (a == NULL){perror("malloc fail!");return 0;}int j = 0;for (int i = 0; i < n; i++){if (fscanf(fout, "%d", &x) == EOF)break;a[j++] = x;}if (j == 0){free(a);return 0;}//排序qsort(a, j, sizeof(int), compare);//写入file1FILE* fin = fopen(file1, "w");if (fin == NULL){free(a);perror("fopen fail!");return 0;}for (int i = 0; i < j; i++){fprintf(fin, "%d\n", a[i]);}free(a);fclose(fin);return j;
}
  • file1file2合并成mfile
void MergeFile(const char* file1, const char* file2, const char* mfile)
{FILE* fout1 = fopen(file1, "r");if (fout1 == NULL){perror("fopen fail!");return;}FILE* fout2 = fopen(file2, "r");if (fout1 == NULL){perror("fopen fail!");return;}FILE* fin = fopen(mfile, "w");if (fin == NULL){perror("fopen fail!");return;}int x1 = 0, x2 = 0;int ret1 = fscanf(fout1,"%d",&x1);int ret2= fscanf(fout2, "%d", &x2);while (ret1 != EOF && ret2 != EOF){if (x1 < x2){fprintf(fin,"%d\n",x1);ret1 = fscanf(fout1, "%d", &x1);}else{fprintf(fin, "%d\n", x2);ret2 = fscanf(fout2, "%d", &x2);}}while (ret1 != EOF){fprintf(fin, "%d\n", x1);ret1 = fscanf(fout1, "%d", &x1);}while (ret2 != EOF){fprintf(fin, "%d\n", x2);ret2 = fscanf(fout2, "%d", &x2);}fclose(fout1);fclose(fout2);fclose(fin);
}
  • 文件归并的主思路
int main()
{CreatData();const char* file1 = "file1.txt";const char* file2 = "file2.txt";const char* mfile = "mfile.txt";FILE* fout = fopen("data.txt", "r");if (fout == NULL){perror("fopen fail!");return 0;}int m = 1000;ReadNDataSortToFile(fout, m, file1);ReadNDataSortToFile(fout, m, file2);while (1){MergeFile(file1, file2, mfile);//删除file1和file2remove(file1);remove(file2);//将mfile改名为file1rename(mfile,file1);//若读不到数据则退出if (ReadNDataSortToFile(fout, m, file2) == 0)break;}return 0;
}

在这里插入图片描述

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

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

相关文章

贪吃蛇(Qt版)

目录 一、项目介绍 界面一&#xff1a;游戏大厅界面 界面二&#xff1a;关卡选择界面 界面三&#xff1a;游戏界面 最终游戏效果&#xff1a; 二、项目创建与资源配置 1. 创建项目 2. 添加项目资源文件 三、项目实现 1. 游戏大厅界面 2. 关卡选择界面 3. 游戏房间界…

TCP 粘包问题

TCP是一个面向字节流的传输层协议。“流” 意味着 TCP 所传输的数据是没有边界的。这不同于 UDP 协议提供的是面向消息的传输服务&#xff0c;其传输的数据是有边界的。TCP 的发送方无法保证对方每次收到的都是一个完整的数据包。于是就有了粘包、拆包问题的出现。粘包、拆包问…

进程的创建、终止

目录 前言1. 进程创建2. 进程终止3. exit && _exit 的异同3.1 相同点3.2 不同点 前言 紧接着进程地址空间之后&#xff0c;我们这篇文章开始谈论进程控制相关的内容&#xff0c;其中包括进程是如何创建的&#xff0c;进程终止的几种情况&#xff0c;以及进程异常终止的…

Android低内存设备系统优化

切记,所有的优化都遵循一条准则: 空间换时间,时间换空间。 一、前言 我们为什么会觉得卡顿、不流畅? 卡顿等性能问题的最主要根源都是因为渲染性能,Android系统很有可能无法及时完成那些复杂的界面渲染操作。Android系统每隔16ms发出信号,触发对UI进行渲染,如果每次渲染…

Thinkphp6 反序列化漏洞分析

本文来自无问社区&#xff0c;更多实战内容可前往查看http://wwlib.cn/index.php/artread/artid/10431.html 版本&#xff1a;Thinkphp6&PHP7.3.4 TP 环境搭建利用 composer 命令进行&#xff0c;同时本次分析在 windows 环境下进行 composer create-project topthink/t…

Android 架构模式之 MVP

目录 架构设计的目的对 MVP 的理解代码ModelViewPresenter Android 中 MVP 的问题试吃个小李子ModelViewPresenter效果展示 大家好&#xff01; 作为 Android 程序猿&#xff0c;你有研究过 MVP 架构吗&#xff1f;在开始接触 Android 那一刻起&#xff0c;我们就开始接触 MVC…

高频变压器无功补偿怎么做

高频变压器的无功补偿主要是为了提高功率因数、减小无功损耗、提高电源利用率。在高频电路中&#xff0c;由于频率较高&#xff0c;传统的无功补偿方法需要进行一定的调整和优化。以下是高频变压器无功补偿的一些方法和建议&#xff1a; 1、无功补偿电容器 高频电容器选择&…

具有手势识别的动捕设备——mHand Pro VR数据手套

数据手套是指通过手套内置的传感器&#xff0c;实时采集手部运动数据的动捕设备&#xff0c;通常被应用于虚拟仿真、虚拟现实vr交互、动画制作等领域。其中&#xff0c;基于惯性动作捕捉技术研发的数据手套&#xff0c;凭借其高性价比的优势&#xff0c;在市面上的应用更为广泛…

STM32G474按钮输入和点灯

在获取到工程模板后&#xff0c;学习某个CPU的第一步通常都是IO口操作。因此按钮输入和点灯&#xff0c;就是本次学习的第一个程序。先从简单入手。 和GPIO操作有关的函数如下: __HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟 __HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIOB时钟 _…

深度理解指针(2)

hello各位小伙伴们&#xff0c;关于指针的了解我们断更了好久了&#xff0c;接下来这几天我会带领大家继续我们指针的学习。 目录 数组名的理解 使用指针访问一维数组 一维数组传参的本质 二级指针 指针数组 使用指针数组来模仿二维数组 数组名的理解 我们首先来看一段…

【开源社区】Elasticsearch(ES)中 exists 查询空值字段的坑

文章目录 1、概述2、使用 null_value 处理空值3、使用 exists 函数查询值为空的文档3.1 使用场景3.2 ES 中常见的空值查询方式3.3 常见误区3.4 使用 bool 查询函数查询空值字段3.5 exists 函数详解3.5.1 bool 查询的不足3.5.3 exists 的基本使用 3.6 完美方案 1、概述 本文主要…

单例模式 详解

单例模式 简介: 让类只初始化一次, 然后不同的地方都能获取到同一个实例 这是非常常用的一种模式, 系统稍微大一点基本上都会用到. 在系统中, 不同模块的总管理类都已单例模式居多 这里我们不仅使用c实现单例模式, 也会用python2实现一遍 python代码 想要看更详细的python单…

手动下载Sentinel-1卫星精密轨道数据

轨道信息对于InSAR&#xff08;干涉合成孔径雷达&#xff09;数据处理至关重要&#xff0c;因为它影响从初始图像配准到最终形变图像生成的整个过程。不准确的轨道信息会导致基线误差&#xff0c;这些误差会以残差条纹的形式出现在干涉图中。为了消除由轨道误差引起的系统性误差…

Swift 6.0 如何更优雅的抛出和处理特定类型的错误

概述 从 Swift 语言诞生那天儿起&#xff0c;它就不厌其烦一遍又一遍地向秃头码农们诉说着自己的类型安全和高雅品味。 不过遗憾的是&#xff0c;作为 Swift 语言中错误处理这最为重要的一环却时常让小伙伴们不得要领、满腹狐疑。 在本篇博文中&#xff0c;您将学到如下内容&…

基于网格尺度的上海市人口分布空间聚集特征分析与冷热点识别

在上篇文章提到了同一研究空间在不同尺度下的观察可能会带来不同的见解和发现&#xff0c;这次我们把尺度缩放到网格&#xff0c;来看网格尺度下的空间自相关性、高/低聚类&#xff0c;这些&#xff0c;因为尺度缩放到网格尺度了&#xff0c;全国这个行政区范围就显的太大了&am…

基于Shader实现的UGUI描边解决方案遇到的bug

原文链接&#xff1a;https://www.cnblogs.com/GuyaWeiren/p/9665106.html 使用这边文章介绍的描边解决方案时遇到了一些问题&#xff0c;就是文字的描边经常会变粗&#xff0c;虽然有的时候也可以正常显示描边&#xff0c;但是运行一会儿描边就不正常了&#xff0c;而且不正常…

UDP+TCP

一、UDP协议 1.recvfrom:recvform(int sockfd,void *buf,size_t len,int flags,struct sockaddr *src_addr,socklen_t *addrlen); 参数&#xff1a;socket的fd; 保存数据的空间地址 &#xff1b; 空间大小&#xff1b; 默认接收方式&#xff08;默认阻塞&#xf…

【案例56】安全设备导致请求被拦截

问题现象 访问相关报表 第二次访问发现有相关的连接问题 问题分析 服务器访问相关节点&#xff0c;发现相关节点无此问题。从客户的客户端访问缺有问题。在nclog中发现如下日志&#xff0c;链接被重置。 直接访问服务器无丢包现象。客户端未开防火墙。装了杀毒软件已经卸载。…

简单记录:两台服务器如何超快速互传文件/文件夹

在服务器间传输文件和文件夹是一个常见的任务&#xff0c;尤其是在需要同步数据或进行备份时。以下是使用 scp 命令在两台服务器之间进行文件传输的基本步骤。 服务器A 至 服务器B&#xff1a;文件传输指南 前提条件 确保服务器A和服务器B之间网络互通。确认您有权限访问目标…

C语言 之 整数在内存中的存储、大小端字节序和字节序的判断

文章目录 整数在内存中的存储大小端字节序和字节序判断大小端有大小端的原因高位和地位怎么区分&#xff1f;图例判断机器大端还是小端的例题 整数在内存中的存储 整数的2进制表示方法有三种&#xff0c;即 原码、反码和补码 三种表示方法均有符号位和数值位两部分&#xff0c…