快速排序原理及实现(c语言实现,超详细)
代码是全的,全部复制粘贴就可以使用。用vs的小伙伴记得把scanf的_s安全检查去掉哦。这是我的第一篇博客,如果有不足之处希望大家指正在留言区指正。
前言:
.
偶也是一个新手,在自学数据结构时了解到了这个排序算法,自己就产生了很浓厚的兴趣然后就研究了一下,不过这个排序算法据说是面试常考的一个题目,以下是我个人的一些心得。冒泡排序和快排一样,都是属于交换类的排序, 快话不多说,先举个栗子。
栗子:
比如我们对16,12,14,13,15这5个数进行快排(从小到大)。
变量说明:
low为数组下限位置,high为数组上限位置,important为待排序字符在排序完成的数列中的位置(即满足左边的数都小于他,右边的数都大于他的位置)。
第一步:
.
先定义low=1和high=数组的长度,令important=low,先移动high(条件满足情况下),将important处的数和high处的数进行比较,因为16>15,所以进行15和16交换,交换完成后开始移动low(条件满足情况下),因为没有数比16大,low会不断+1所以最后high和low会停留在5这个位置上,5就是我们要找的位置,所以important最后=5,16在5位置时6的左边的数都小于它,右边的数都大于它。
排序前 | 16 | 12 | 14 | 13 | 15 |
---|---|---|---|---|---|
排序后 | 15 | 12 | 14 | 13 | 16 |
初始 | low | high | |||
排序后 | low high |
第二步:
.
现在16的位置已经定了,我们开始对16的左半部分进行排序。我们先对15进行排序,使得15左边的数都小于他,右边的数都大于他,这个时候low=1和high=4,important=low, 先移动high(条件满足情况下 ),同上,15和13进行交换,然后移动low,因为没有数比15大,所以最后low=high=4,15在4位置时左边的数都小于他,右边的数都大于他。
排序前 | 15 | 12 | 14 | 13 | 16 |
---|---|---|---|---|---|
排序后 | 13 | 12 | 14 | 15 | 16 |
初始 | low | high | |||
排序后 | low high |
第三步:
.
现在16,15的位置都已经定了,我们让low=1,high=3,important=12,判
断12<14,所以high-1,因为13>12,所以进行交换,13和12交换。13在2位置时,左边的数都小于他,右边的数都大于他。
排序前 | 13 | 12 | 14 | 15 | 16 |
---|---|---|---|---|---|
排序后 | 12 | 13 | 14 | 15 | 16 |
初始 | low | high | |||
排序后 | low high |
第四步:
.
同上,但是不做任何交换。因为12已经满足左边的数小于他,右边的数大于他。
排序前 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|
排序后 | 12 | 13 | 14 | 15 | 16 |
初始 | low | high | |||
排序后 | low high |
快排的核心思想:
.
1.将每一个数都放置在一个正确的位置上,使得该数的左边的所有数都小于他,右边的所有数都大于他,当每个数都满足这个条件时,数列排序完成。
2. 因为对每一步的处理有相似性,所以可以用递归和分治方法实现。
3. 将一个数组通过产生important拆分成2个小数组段,同时对这两个数组进行排序,提高效率
代码块
1. 首先看一下要排序的数组的结构体
typedef struct data
{int number[10];int length;
}Data;
2.定位important的代码
int found_important(Data* p, int low, int high)//寻找中点
{int important;int temp;important = p->number[low];
while (low < high){while (low<high && important>p->number[high])//找右边位置(控制排序方向)high--;temp= p->number[high];//交换数据,确保imporant的右边都小于他p->number[high] = p->number[low];p->number[low] = temp;while (low<high && important<=p->number[low]) //找左边位置(控制排序方向)low++;temp = p->number[high];//交换数据,确保imporant的左边都大于他p->number[high] = p->number[low];p->number[low] = temp;}return low;//当low==high时,退出循环
3递归确定每一个数的位置
void quickSort(Data *p,int low,int high)
{int important;if (low < high){important = found_important(p, low, high);//记录中点位置//分治思想quickSort(p, low, important-1);//确定左边数列顺序quickSort(p, important+1, high);//确定右边数列顺序}
}
4.main函数
int main()//快速排序(从大到小)
{Data array;Data* p=&array;int i;//用于控制循环printf("请输入要排序的数组个数\n");scanf_s("%d", &p->length);printf("请输入待排序的数组\n");for (i = 1; i < p->length+1; i++){scanf_s("%d",&p->number[i]);}quickSort(p, 1, p->length);printf("数据排序后是:\n");for (i=1;i<p->length+1;i++){printf("%5d",p->number[i]);}return 0;
}
复杂度分析:
到这里就差不多结束了
我们现在来看一下程序的复杂度吧!
假设一个待排序的数组有n个元素
一次寻找important的循环需要遍历数组一次,所以定位important的函数found_important的时间复杂度是O(n);
时间复杂度:
最好情况:
每一次都是对数组的对分,那么通过多个线程(提高速度的关键)对同时对子问题进行运算,那么就要运行log(以2为底) n次程序,所以最终的复杂度就是O(n×log(以2为底)n)。
最坏情况:
(上述栗子就是最坏情况)
每次的impotent都是子数组的最大或最小元素,使得数组无法被拆分运算,那么总共要运行n次,所以最终的时间复杂度为(n×n)。
平均上述情况,该算法的复杂度最终为O(n*log(以2为底)n)。
空间复杂度:
最好情况:
即快速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度为log2(n+1)。
最坏情况:
栈的最大深度为n。这样,快速排序的空间复杂度为O(log2n))。
因为存在对数,所以当数据量很大时,快排的优势就特别明显了。
因此,该排序方法被认为是目前最好的一种内部排序方法。
参考资料:
1.快速排序百度百科
2.《大话数据结构》 -成杰著
快速排序原理及实现(c语言实现,超详细)相关推荐
- 一步一步教你从零开始写C语言链表(超详细)
STM32 HAL开发完全指南 写文章 一步一步教你从零开始写C语言链表(超详细) 杨源鑫 嵌入式系统工程师.物联网创业合伙人,业务经理兼产品经理 285 人赞同了该文章 为什么要学习链表? 链表主要 ...
- 三、Hive数据仓库应用之Hive数据操作语言(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
Hive远程模式部署参考: 一.Hive数据仓库应用之Hive部署(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7) Hive数据定义语言 ...
- msp430流水灯c语言程序,超详细msp430示例程序汇编.doc
超详细msp430示例程序汇编 一.基础_实验[10个] 1.入门试验:LED闪烁(1个) 2.时钟实验:设置MCLK.ACLK.SMCLK(1个) 3.低功耗实验:设置低功耗模式(1个) 4.IO端 ...
- 如何学习C语言,超详细的经验分享(学习笔记1--C语言的基本数据类型)
前言: 如果你正在学习C语言而又不知道从何处开始学,你可以跟着我一起学习C语言,在寒假期间我每天都会发一篇博客,里面有各种C语言的知识点,如果你想学习下去,想进步,就来每天跟着我一起打卡吧,期待我们能 ...
- C语言:超详细的C语言中的数据类型
程序=算法+数据结构: (数据结构的核心是数据,数据呢得有类型)(算法就是在数据上做一些相关的操作) 数据类型:是程序设计语言预先做好的工具,每种类型处理一类数据(比如有处理整型数的工具,处理实型数的 ...
- 数据结构-带头节点的单链表(C语言)超详细讲解
前面我们学到线性表的顺序存储结构(顺序表),发现它有着明显的缺点:插入和删除元素时需要频繁的移动元素,运算效率低.必须按事先估计的最大元素个数申请连续的存储空间.存储空间估计大了,造成浪费空间:估计小 ...
- 【C语言】超详细的移位、位操作符详解(含力扣实战)
目录 ?1.整数的二进制表示 ?2.移位操作符 ?2.1左移操作符(低位补0) ?举例 ?原理分析 ??2.2右移操作符 ?算术右移&#x
- Adaboost算法原理以及matlab代码实现(超详细)
一.AdaBoost简介 Boosting, 也称为增强学习或提升法,是一种重要的集成学习技术, 能够将预测精度仅比随机猜度略高的弱学习器增强为预测精度高的强学习器,这在直接构造强学习器非常困难的情况 ...
- 判断是否为质数的超级优化 C++语言(超详细)
首先我们要知道质数的概念: 质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 知道了质数的概念,我们就可以大胆的说:"老师 ...
- 【STM32】GPIO工作原理(八种工作方式超详细分析,附电路图)
STM32F1xx官方资料: <STM32中文参考手册V10>-第8章通用和复用功能IO(GPIO和AFIO ) 芯片数据手册(datasheet) STM32的GPIO介绍 STM32引 ...
最新文章
- Wrong permissions on configuration file, should not be world writable!
- linux 云主机 卡顿 排查过程
- UA PHYS515A 电磁理论V 电磁波与辐射7 运动点电荷的辐射
- 【软件工程】技术规格说明书
- 每次digital painting 之后,都可以把作品放到这里,比较好看,也和nft相关度比较大
- step-by-step多文件WEB批量上传(swfupload)的完美解决方案
- vscode 标准库位置_如何在VSCode中使用标准
- shiro学习(19): 拦截器
- python序列符号_初识Python(4)__Python序列
- 很火的仿soul交友盲盒1.0全开源源码
- 做企业:要么靠规模,要么靠利润
- Android水波纹特效的简单实现
- HTTP 权威指南 详解 (推荐阅读 )
- java8配置环境变量_java8环境变量设置
- 你要如何衡量你的人生
- 分享几款好用的强力数据恢复软件
- W10虚拟机一开机电脑蓝屏重启
- SRM 405(1-250pt, 1-500pt)
- c#语言编写汉诺塔游戏,c#语言编写汉诺塔游戏
- 用python处理excel数据、求线性回归方程的r值_Python 线性回归计算r-squared方法