数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件IO+大数据排序+文件合并

  • 第一章 冒泡排序
    • 【1】Bubble_Sort.c
  • 第二章 快速排序
    • 【1】quick_sort.c
  • 第三章 大数据排序
    • 【1】calloc
    • 【2】malloc
    • 【3】readlloc
    • 【4】文件IO操作
      • 【4.1】fprintf
      • 【4.2】fscanf
      • 【4.3】fnprintf
      • 【4.4】rename 和remove函数

如果你真的看不懂,那就死记硬背,如果你不想背,那就珍藏吧

第一章 冒泡排序


冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

【1】Bubble_Sort.c

/** @Author: your name* @Date: 2021-09-03 14:09:13* @LastEditTime: 2021-09-03 15:35:44* @LastEditors: Please set LastEditors* @Description: In User Settings Edit* @FilePath: \Desktop\bb.c*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>#define SIZE    10000//冒泡排序   从小到大
void bubble_sort(int *arr, int len)//100
{int sort_count, pos;int tmp;//排序多少次:sort_count:计数已经排好了几个数据,len-1:最后一个不用排序for(sort_count=0; sort_count<len-1; sort_count++){//pos:从哪个位置开始比较,len-sort_count-1:总的数据长度-已经排好的数据个数-1(这个-1是因为pos下面的操作中会访问到pos+1)for(pos=0; pos<len-sort_count-1; pos++){if(arr[pos] > arr[pos+1])//前面的数据{//交换数据tmp = arr[pos];arr[pos] = arr[pos+1];arr[pos+1] = tmp;}}}}int main(void)
{int *array = malloc(SIZE*sizeof(int));int i;srand(time(NULL));//随机数种子for(i=0; i<SIZE; i++){array[i] = rand()%SIZE;//开始种子}bubble_sort(array, SIZE);//排序函数for(i=0; i<SIZE; i++)//打印{printf("%d ", array[i]);}printf("\n");return 0;
}

第二章 快速排序

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
挑选基准值:从数列中挑出一个元素,称为"基准"(pivot);

分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;

递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

【1】quick_sort.c

/** @Author: your name* @Date: 2021-09-03 15:21:41* @LastEditTime: 2021-09-03 15:34:54* @LastEditors: Please set LastEditors* @Description: In User Settings Edit* @FilePath: \Desktop\quick.c*/
/***********************************************  File Name: quick.c*  Created  @ 2016-08-03 21:20*  Author   : Gec*  E-mail   : 2034294993@qq.com**********************************************/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>#define SIZE    100000void quick(int arr[],  int left, int right)//left=0   right=100000-1
{int i;if(left < right){int tmp = arr[left];//第一个值给临时变量,腾出第一个位置int low = left;//低位0int high = right;//高位99999//快速排序交替比较while(low < high)//循环在左下标小于右下标的基础上{//从右到左比较,实时判断左下标有没有小于右下标的值,并且右值有没有小于中间的交换值while(low < high && arr[high] >= tmp){high--;//直到减到不满足条件,这个值arr[high]要么==tmp  or<tmp }//当跳出循环时,也就是第一位:后面的数字都和第一位一一比较过了//证明,第一位真的是最小的了,此时就该记录一下,arr[low] = arr[high];//把右值放到腾出来的空间中//从左到右比较,实时判断左下标有没有大于或者等于右下标的值,并且右值有没有小于中间的交换值while(low < high && arr[low] < tmp)//注意,此时high值上面已经改变了{low++;}arr[high] = arr[low];}//最后剩下的位置,就是空出来的那个,然后就排序好了arr[low] = tmp;quick(arr,left,low-1);//左quick(arr,low+1,right);//右}
}int main(int argc, char **argv)
{int *array = malloc(SIZE*sizeof(int));int i;srand(time(NULL));//种子for(i=0; i<SIZE; i++){array[i] = rand()%SIZE;//产生随机数}quick(array, 0, SIZE-1);// 0--8 是下标for(i=0; i<SIZE; i++)//打印{printf("%d ", array[i]);}printf("\n");return 0;
}

第三章 大数据排序

这里需要运用文件io的方法

【1】calloc

calloc函数的功能与malloc函数的功能相似,都是从堆分配内存。其函数声明如下:
void *calloc(int n,int size);
参数释义:
size:每块多少大小
n:申请的块数
注意:最后申请空间大小为: n和size相乘

【2】malloc

malloc函数可以从堆上获得指定字节的内存空间,其函数声明如下:
void * malloc(int n);
参数释义:
n:申请空间大小(单个类型大小*总个数)

【3】readlloc

适用情况一般是mallloc申请的大小不够用了,需要扩充
原型:extern void *realloc(void mem_address, unsigned int newsize);
语法:指针名=(数据类型
)realloc(要改变内存大小的指针名,新的大小)。
//新的大小若小于原来的大小,原数据的末尾可能丢失(被其他使用内存的数据覆盖等)
头文件:#include <stdlib.h> 有些编译器需要#include <malloc.h>

【4】文件IO操作

【4.1】fprintf

【4.2】fscanf

【4.3】fnprintf

// 打开一个包含百万数据级别的文件FILE *src = fopen("numbers.txt", "r");//只读方式打开if(src == NULL){perror("打开文件失败");exit(0);//结束程序}

int fscanf ( FILE *fp, char * format, … );
int fprintf ( FILE *fp, char * format, … );

输入文件操作:src是文件描述符
%u:是从文件取的格式,显然是unsigned int类型
&data[i]:数组地址
返回值:失败返回EOF=-1
fscanf(src, "%u", &data[i])

原型:int snprintf(char *str, size_t size, const char *format, …);

描述:The functions snprintf() write at most size bytes (including the terminating null byte (‘\0’)) to str. 即snprintf这个函数按照format格式最多将size个字符写入到str中,其中size个字符已经包括了结束符。

【4.4】rename 和remove函数

rename 命令通过字符串替换的方式批量修改文件名。
格式:rename from to file
from : 表示需要替换或需要处理的字符,一般是文件名称的一部分,
to :将 from 内容,替换成 to 的内容。
file :待处理的文件。
remove(f1);//删除f1文件描述符
/** @Author: your name* @Date: 2021-09-03 15:43:04* @LastEditTime: 2021-09-03 15:45:06* @LastEditors: Please set LastEditors* @Description: In User Settings Edit* @FilePath: \Desktop\big_data_sort.c*/
#include <stdio.h>
#include <stdbool.h>//交换两个数
void swap(int *a, int *b)//当参数是指针时,你对a,b所有的操作都会保留值,而且不用return 形式
{int tmp;tmp = *a;*a = *b;*b = tmp;
}// 融合begin到end的所有文件,并入文件begin=1
void merge(int begin, int end)//end=20
{if(end-begin <= 0)return;// 融合begin+1到end的所有文件,并入文件begin+1merge(begin+1, end);//递归自己// 合并begin和begin+1char f1[10], f2[10];bzero(f1, 10);bzero(f2, 10);//将begin.txt个文件存入fxsnprintf(f1, 10, "%d.txt", begin);snprintf(f2, 10, "%d.txt", begin+1);//printf("正在合并%s和%s...\n", f1, f2);FILE *fp1 = fopen(f1, "r");FILE *fp2 = fopen(f2, "r");unsigned n1, n2;if(fscanf(fp1, "%u", &n1) == EOF){fclose(fp1);fclose(fp2);remove(f1);//删除rename(f2, f1);//重命名f2为f1return;}if(fscanf(fp2, "%u", &n2) == EOF){fclose(fp1);fclose(fp2);remove(f2);return;}// 临时存放合并的数据,最后更名为beginFILE *tmp = fopen("tmp.txt", "w+");//读写方式打开文件int fp1_done = false;int fp2_done = false;while(1){if(n1 < n2)//两个文件描述符的比较{fprintf(tmp, "%u\n", n1);//tmp文件描述符=n1(fp1)文件内容if(fscanf(fp1, "%u", &n1) == EOF)//{fprintf(tmp, "%u\n", n2);fp1_done = true;break;}}else{fprintf(tmp, "%u\n", n2);if(fscanf(fp2, "%u", &n2) == EOF){fprintf(tmp, "%u\n", n1);fp2_done = true;break;}}}// 将剩余的数据置入tmp中if(fp1_done){while(fscanf(fp2, "%u", &n2) != EOF){fprintf(tmp, "%u\n", n2);}}else{while(fscanf(fp1, "%u", &n1) != EOF){fprintf(tmp, "%u\n", n1);}}// 删除原有文件,并将tmp更名为beginfclose(fp1);fclose(fp2);if(remove(f1) == -1){printf("删除文件%s失败:%s\n", f1, strerror(errno));exit(0);}if(remove(f2) == -1){printf("删除文件%s失败:%s\n", f2, strerror(errno));exit(0);}fclose(tmp);rename("tmp.txt", f1);
}int main(int argc, char **argv)
{// 打开一个包含百万数据级别的文件FILE *src = fopen("numbers.txt", "r");//只读方式打开if(src == NULL){perror("打开文件失败");exit(0);//结束程序}// 1,将原始数据文件,分割成N个有序的子文件bool done = false;char file[20];int N = 0;int wanted = 10*10000; // 假设每次只能读取10万个数据int infact = wanted;//狂铁:10万伏特while(1){// 试图从文件读取 wanted 个数据unsigned *data = calloc(wanted, sizeof(unsigned));//申请10万块,每块4字节for(int i=0; i<wanted; i++){if(fscanf(src, "%u", &data[i]) == EOF)//从文件numbers.txt取出无符号类型的数据存入data数组{done = true;infact = i;break;}}// 对这读到的 infact 个数据进行排序quickSort(data, infact);//快速排序// 创建临时文件,存放部分数据bzero(file, 20);//file数组名,20数组大小,格式,存入数据  举例:file[0]=0.txtsnprintf(file, 20, "%d.txt", ++N);//用来装文件名,最多存20个.txt的文件名FILE *fp = fopen(file, "w");//只写方式// 将排好序的部分数据写入临时文件,保存起来for(int i=0; i<infact; i++){fprintf(fp, "%u\n", data[i]);}free(data);fclose(fp);if(done)break;}fclose(src);// 2,将N个有序子文件,合并成一个有序文件merge(1, N);return 0;
}

创作真的不容易,但能帮助人,腰酸一点又有什么关系

数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件IO+大数据排序+文件合并相关推荐

  1. 掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)...

    掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等). 数组高级以及Arrays(掌握) 排序方法 空间复杂度 时间复杂度 稳定性 插 入 排 序 ...

  2. 大数据排序方案---外排序介绍

    原文:http://blog.sina.com.cn/s/blog_62186b4601019uz1.html 我们一般提到排序都是指内排序,比如快排,堆排序,归并排序等,所谓内排序就是能把所有待排序 ...

  3. Java开发在线购物推荐网 购物商城推荐系统 基于用户、物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、人工智能、机器学习项目开发

    Java开发在线购物推荐网 购物商城推荐系统 基于用户.物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据.人工智能.机器学习项目开发Sh ...

  4. Java语言开发在线美食推荐网 美食推荐系统 基于用户、物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis框架 人工智能、大数据、机器学习项目开发

    Java语言开发在线美食推荐网 美食推荐系统 基于用户.物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis框架 人工智能.大数据.机器学习项目开发FoodRecomm ...

  5. 在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户、物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据、机器学习、人工智能开发

    在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户.物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据.机器学习.人工智能开发 CarRecom ...

  6. 一文通数据结构与算法之——链表+常见题型与解题策略+Leetcode经典题

    文章目录 1 链表 1.1 常见题型及解题策略 1.1.1 LeetCode中关于链表的题目有以下五种类型题: 1.1.2 解题策略 1.2 链表的基本内容 1.2.1 链表的基本结构: 1.2.2 ...

  7. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

  8. 八大排序算法(java实现) 冒泡排序 快速排序 堆排序 归并排序 等

    八大排序算法 一.直接插入 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 二.希尔排序 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 三.简单选择 - 1. ...

  9. 中希尔排序例题代码_十大经典排序算法最强总结

    排序算法属于经典基础算法基本功,笔试面试基本都会涉及和考察的,有原题也有变化,不过基础的几大排序算法还是得尽可能熟悉,能在思路熟悉的前提下手写出代码就更好了. ❝为了防止不提供原网址的转载,特加原文链 ...

最新文章

  1. Android中去掉标题的方法总结
  2. typedef 函数指针的用法
  3. [转]UTF-8 GBK UTF8 GB2312 之间的区别和关系
  4. django makemigrtions时出现no changes detected 解决方式
  5. netbeans6.8_NetBeans 8.0的五个新性能提示
  6. Jenkins 在Windows下插件无法安装问题解决
  7. 用Java获取当前工作目录
  8. 2018年千锋Java微服务架构视频教程
  9. ArcGIS与地理加权回归GWR【一】
  10. 翻译记忆软件-塔多思TRADO经典教程_5
  11. 零跑C01/S01/C11/T03维修手册电路图培训手册用户手册技术资料
  12. 台式计算机如何组装,怎样组装基本台式机
  13. 解决其他浏览器能上网谷歌浏览器不能上网
  14. 科技爱好者周刊(第 209 期):程序员是怎样的人
  15. 电子宠物游戏(附C++源码)
  16. ps如何快速消除黑眼圈或者眼袋
  17. 视频显著性检测----《Flow Guided Recurrent Neural Encoder for Video Salient Object Detection》
  18. read_csv()报错: 'utf-8' codec can't decode byte 0xca in position 0: invalid continuation byte最新解决办法
  19. 获取当前日期(年月日)
  20. H5人脸实名认证-百度云版

热门文章

  1. 360 搜索 VS Google VS 百度搜索
  2. 爬虫技巧整合(持续更新~)
  3. 2021-2027全球及中国合成孔径雷达卫星服务行业研究及十四五规划分析报告
  4. 总结一下这两天的学习笔记
  5. 题解 P2285 【[HNOI2004]打鼹鼠】
  6. oracle缩表空间大小,Oracle查询锁 表空间名称和大小 被锁的表
  7. 再探勒索病毒之删除卷影副本的方法
  8. [Linux] Ansible及playbook实操步骤
  9. 【STM32】STM32 OLED打点划线画圆 OLED电子罗盘 程序
  10. LXD 2.0 系列(八):LXD中的LXD