数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件IO+大数据排序+文件合并
数据结构与算法 第八天常见排序+冒泡排序+快速排序+文件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+大数据排序+文件合并相关推荐
- 掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)...
掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等). 数组高级以及Arrays(掌握) 排序方法 空间复杂度 时间复杂度 稳定性 插 入 排 序 ...
- 大数据排序方案---外排序介绍
原文:http://blog.sina.com.cn/s/blog_62186b4601019uz1.html 我们一般提到排序都是指内排序,比如快排,堆排序,归并排序等,所谓内排序就是能把所有待排序 ...
- Java开发在线购物推荐网 购物商城推荐系统 基于用户、物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、人工智能、机器学习项目开发
Java开发在线购物推荐网 购物商城推荐系统 基于用户.物品的协同过滤推荐算法 京东商城爬虫 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据.人工智能.机器学习项目开发Sh ...
- Java语言开发在线美食推荐网 美食推荐系统 基于用户、物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis框架 人工智能、大数据、机器学习项目开发
Java语言开发在线美食推荐网 美食推荐系统 基于用户.物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis框架 人工智能.大数据.机器学习项目开发FoodRecomm ...
- 在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户、物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据、机器学习、人工智能开发
在线车辆推荐网 Python语言+Django框架+Mysql数据库 基于用户.物品的协同过滤推荐算法 开发在线汽车推荐系统 二手车网站推荐系统 分布式大数据.机器学习.人工智能开发 CarRecom ...
- 一文通数据结构与算法之——链表+常见题型与解题策略+Leetcode经典题
文章目录 1 链表 1.1 常见题型及解题策略 1.1.1 LeetCode中关于链表的题目有以下五种类型题: 1.1.2 解题策略 1.2 链表的基本内容 1.2.1 链表的基本结构: 1.2.2 ...
- 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树
文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...
- 八大排序算法(java实现) 冒泡排序 快速排序 堆排序 归并排序 等
八大排序算法 一.直接插入 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 二.希尔排序 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 三.简单选择 - 1. ...
- 中希尔排序例题代码_十大经典排序算法最强总结
排序算法属于经典基础算法基本功,笔试面试基本都会涉及和考察的,有原题也有变化,不过基础的几大排序算法还是得尽可能熟悉,能在思路熟悉的前提下手写出代码就更好了. ❝为了防止不提供原网址的转载,特加原文链 ...
最新文章
- Android中去掉标题的方法总结
- typedef 函数指针的用法
- [转]UTF-8 GBK UTF8 GB2312 之间的区别和关系
- django makemigrtions时出现no changes detected 解决方式
- netbeans6.8_NetBeans 8.0的五个新性能提示
- Jenkins 在Windows下插件无法安装问题解决
- 用Java获取当前工作目录
- 2018年千锋Java微服务架构视频教程
- ArcGIS与地理加权回归GWR【一】
- 翻译记忆软件-塔多思TRADO经典教程_5
- 零跑C01/S01/C11/T03维修手册电路图培训手册用户手册技术资料
- 台式计算机如何组装,怎样组装基本台式机
- 解决其他浏览器能上网谷歌浏览器不能上网
- 科技爱好者周刊(第 209 期):程序员是怎样的人
- 电子宠物游戏(附C++源码)
- ps如何快速消除黑眼圈或者眼袋
- 视频显著性检测----《Flow Guided Recurrent Neural Encoder for Video Salient Object Detection》
- read_csv()报错: 'utf-8' codec can't decode byte 0xca in position 0: invalid continuation byte最新解决办法
- 获取当前日期(年月日)
- H5人脸实名认证-百度云版