前面的博文讲了冒泡排序、选择排序、插入排序,今天我们谈谈快速排序!
快速排序的基本思想是:
1.先从序列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。(分区的方式多样,但一定要保证基准数左边的数比它大(小),右边的数比它小(大))
3.再对左右区间重复第一步、第二步,直到各区间只有一个数。

快速排序的关键点(一定要理解):
1、 如何确定基准数?
一般情况下,选取当前数组的第一个数。
2、如何找到比基准数大(小)的数?(假设从小到大排序)
先从后往前找比基准数小的数;再从前往后找比基准数大的数;(注意次序不能颠倒)
3、找到的数如何放,才能实现比基准数大和小的数分别在基准数的两边?
采用挖坑填数法,具体过程如下:
①每次把基准数所在的位置看成一个坑位A,定义两个变量:left和right分别指向数组的左端和右端。
②从后往前扫描数组,当发现有值小于基准值时,将当前值填到坑位A中,同时当前值所在的位置看成新的坑位B;
③从前往后扫描数组,当发现有值大于基准值,将当前值填到坑位B中,同时当前值所在的位置看成坑位A;
不停的重复第②~③步的操作,直到left>=right相遇,表示这一轮的内循环比较结束,
将基准值填到left(right)指向的坑位中,就完成了本轮的排序;
4、以基准值为分割点,将当前的数组为两个小的数组,依次从第1步递归循环操作;

为了便于学者深入理解,举例:[14, 18, 11, 30, 28,4 ]进行从小到大的排序

整个过程中涉及三个参数:当前基准数num,left,right; (left,right分别代表当前数组的左右端位置)
第1轮:基准数num=14

①交换前的数据:[14, 18, 11, 30, 28,4 ] 当前坑位[0],left=0,right=5
②从right=5的位置开始从后往前,找到比14小的第一个数4,此时的left=0,right=5,满足left<right,把4填到当前的坑位[0];
交换后的数据:[4, 18, 11, 30, 28,4] 当前坑位[5] (4原来的下标位置)
③从left=0的位置开始从前往后,找到比14大的第一个数18,此时的left=1,right=5,满足left<right,把18填到当前的坑位[5],
交换后的数据:[4, 18, 11, 30, 28,18]当前坑位[1](18原来的下标位置),
④从right=5的位置开始从后往前,找到比14小的第一个数11,此时的left=1,right=2,满足left<right,把11填到当前的坑位[1]
交换后的数据:[4,11,11,30,28,18]当前坑位[2](11原来的下标位置)
⑤从left=1的位置开始从前往后,找到比14大的第一个数30,此时的left=3,right=2,
由于left>right,内循环结束,将基准值14放在最后一个坑位[2]的位置。
交换后的数据:[4,11,14,30,28,18]

第1轮结束。(14左边的数都比14小,14右边的数都比14大)

以基准数14为分割点,用{ }划分。表示如下:[{4,11},14,{30,28,18}],

(一)先对14左边的子数组{4,11}进行递归快速排序:
第2轮:基准数num=4(14左边的子数组{4,11})

①交换前的数据:[{4,11},14,{30,28,18}]当前坑位[0], left=0,right=1(因为当前数组为{4,11});
②从right=1的位置从后往前,直到right=0也没有找到比4小的数,此时的left=0,right=0,由于left等于right,内循环结束,将基准值4放在最后一个坑位[0]的位置。
③交换后的数据为:[4,11,14,18,28,30]

第2轮结束。(4左边的数都比4小,4右边的数都比4大)

以基准数4为分割点,用{ }划分。表示如下:[4,{11},14,30,28,18],

第3轮:基准数num=11(4右边的子数组{11})

①交换前的数据:[4,{11},14,30,28,18]当前坑位[1], left=1,right=1(因为当前数组为{11});
由于left等于right,内循环结束,将基准值11放在最后一个坑位[1]的位置。
③交换后的数据为:[4,11,14,18,28,30]

第3轮结束。(11左边的数都比11小,11右边的数都比11大)

(二)先对14右边的子数组{30,28,18}进行递归快速排序:
第4轮,基准值num=30(14右边的子数组{30,28,18})

①交换前的数据:[4,11,14,{30,28,18}] 当前坑位[3],left=3,right=5(因为当前数组为{30,28,18})
②从right=5的位置开始从后往前,找到比30小的第一个数18,此时的left=3,right=5,满足left<right,把18填到当前的坑位[3];
交换后的数据:[4,11,14,{18,28,18}] 当前坑位[5] (18原来的下标位置)
③从left=3的位置开始从前往后,直到left=5也没有找到比30大的数,此时的left=5,right=5,
由于left等于right,内循环结束,将基准值30放在最后一个坑位[5]的位置。
交换后的数据:[4,11,14,18,28,30]

第4轮结束。

以基准数30为分割点,用{ }划分。表示如下:[4,11,14,{18,28},30]

第5轮:基准值num=18(30左边的子数组{18,28})

①交换前的数据:[4,11,14,{18,28},30]当前坑位[3], left=3,right=4(因为当前数组为{18,28})
②从right=4的位置开始从后往前,直到right=3都没有找到比18小的数,此时的left=3,right=3,由于left等于right,内循环结束,将基准值18放在最后一个坑位[3]的位置。

第5轮结束

以基准数18为分割点,用{ }划分。表示如下:[4,11,14,18,{28},30]

第6轮:基准值num=28(18右边的子数组{28})
①交换前的数据:[4,11,14,18,{28},30]当前坑位[4], left=4,right=4,由于left等于right,内循环结束, 将基准值28放在最后一个坑位[4]的位置。
②交换后的数据为:[4,11,14,18,28,30]

第6轮结束

排序后最终的数组为:[4,11,14,18,28,30]

对挖坑填数进行如下总结:三个参数基准数,left(i),right(j)(假设有n个数)
1.i =left; j = right; 将基准数挖出形成第一个坑a[i]。
2.j–由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

整个快速排序的时间复杂度仍然是O(n的平方);
快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

为了便于道友们向我咨询问题,特意开设了一个免费的知识星球——CaptianXue,星球提供学习、理财、生活、职场等各类文章和免费答疑!!

完整的代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
void quickSort(int s[], int left, int right) {if (left< right) { //只有当left<right的时候才执行快速排序int i = left, j = right, x = s[left];//初始值 while (i < j) {//只要i<j就一直循环从后往前找,从前往后找; while(i < j && s[j]>= x) // 从右向左找第一个小于x的数j--;if(i < j)s[i++] = s[j];//进行填数 while(i < j && s[i]< x) // 从左向右找第一个大于等于x的数i++;if(i < j)s[j--] = s[i];//进行填数 }s[i] = x; //把基准数填入 quickSort(s, left, i - 1); //当前基准数左边的子数组递归调用quickSort(s, i + 1, right);//当前基准数右边的子数组递归调用}
}
int main() {int s[]= {14,18,11,30,28,4 };printf("原来的数组为:\n");for(int i=0; i<6; i++)printf("%d ",s[i]);printf("\n");quickSort(s,0,5);//调用快速排序的函数,参数为数组名,数组的左端点,数组的右端点printf("排序后的数组(从小到大)为:\n");for(int i=0; i<6; i++)printf("%d ",s[i]);printf("\n");return 0;
}

当然,还有一种快速排序,选取当前数组中首,尾,中三个数的中位数,即大小居中的数为基准数。其他的操作过程不变!学者可以自我实现。

更多的排序算法:
sort函数排序 https://blog.csdn.net/weixin_43956598/article/details/90241551
冒泡排序 https://blog.csdn.net/weixin_43956598/article/details/90176251
选择排序 https://blog.csdn.net/weixin_43956598/article/details/90178197
插入排序 https://blog.csdn.net/weixin_43956598/article/details/90181567
快速排序 https://blog.csdn.net/weixin_43956598/article/details/90215135
希尔排序 https://blog.csdn.net/weixin_43956598/articledetails/90234480
堆排序 https://blog.csdn.net/weixin_43956598/article/details/90343547

快速排序(Quick Sort)—挖坑填数法相关推荐

  1. 一次partition过程一(挖坑填数法)

    题目描述 快排的关键在于划分(partition操作),一次划分过程有很多实现的思路.请对a[1].a[2].....a[n]实现一次partition,并输出结果. 要求:使用"挖坑法&q ...

  2. 一头扎进算法导论-快速排序(挖坑填数策略)

    定义:它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到 ...

  3. 数据结构-挖坑填数+分治法解决快速排序问题(java+c)

    文章目录 一.定义 1.分治法 2.挖坑填数 3.快速排序思想 二.代码实例 1.Java 2.c语言 看到网上有很多的讲解,决定自己整理一遍 首先上定义 一.定义 1.分治法 分治算法的基本思想是将 ...

  4. 快速排序 Quick Sort

    快速排序 Quick Sort 我们已经知道,在决策树计算模型下,任何一个基于比较来确定两个元素相对位置的排序算法需要Ω(nlogn)计算时间.如果我们能设计一个需要O(n1ogn)时间的排序算法,则 ...

  5. 快速排序 (Quick Sort)(Java实现)

    快速排序(Quicksort)是对冒泡排序的一种改进,借用了分治的思想,由C. A. R. Hoare在1962年提出. 1.基本思想 快速排序的基本思想:挖坑填数+分治法. 首先选一个轴值(pivo ...

  6. 【排序算法】快速排序(Quick Sort)

    快速排序(Quick Sort)使用分治法算法思想. 快速排序介绍 它的基本思想是: 选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小. ...

  7. Golang TDD实践报告:快速排序Quick Sort

    Golang TDD实践报告:快速排序Quick Sort [阅读时间:约5分钟] 0.项目需求 1.编写符合项目输入输出的一个测试 2.尝试运行测试 3.先使用最少的代码来让失败的测试先跑起来 4. ...

  8. C语言快速排序 quick sort 算法(附完整源码)

    快速排序 quick sort 算法 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) # ...

  9. 奇数幻方的经典解决方法--右上方填数法

    幻方,也教纵横图,就是在n×n的方阵中放入1到n 2个自然数:在一定的布局下,其各行.各列和两条对角线上的数字之和正好都相等.这个和数就叫做"幻方常数"或幻和. 构造幻方的方法: ...

最新文章

  1. 2018-07-12 第六十七天 EsayUI
  2. Oracle Net Configuration(监听程序和网络服务配置)
  3. 【研发管理】结构化流程框架
  4. linux echo写php编码,linux使用和基础操作(示例代码)
  5. 单例模式——Java
  6. java socket优化_Java Socket编程代码优化
  7. AlertDialog禁止返回键
  8. 10打开没有反应_118个遇水反应化学品清单及高压反应釜操作经验
  9. getHibernateTemplate()为NUll
  10. sping 总结(03)springmvc
  11. mysql5.7.11源码安装_centos 7.0安装MySQL Community Server 5.7.11 源码编译安装
  12. 如何创建PDF格式文件,这个方法教你快速创建
  13. 雨滴win7计算机路径,Rainmeter雨滴桌面Win7打不开怎么办?
  14. 彻底解决tplink路由器无法访问部分https网站
  15. MD5值的简介和查看
  16. 谷歌浏览器翻译插件方便阅读方法,收藏备用
  17. Google Maps JavaScript API 使用
  18. [android][马达]振动反馈-转子马达效果参数配置
  19. 利用CRM客户管理系统抓住销售商机
  20. 2023 年 4 月脚本神器合集来了

热门文章

  1. linux中realplayer.rpm格式的软件安装,Linux系统中Realplay 10.0的安装和使用
  2. 分享113个ASP搜索链接源码,总有一款适合您
  3. 2021.02.04——用爬虫爬取nga ow区1-10页的帖子并生成词云图
  4. 获得当前时间的格林威治时间毫秒数
  5. 数据预处理过程中处理方法
  6. 2018年全国心理测试技术研究、应用及专业人员培养研讨会活动简报
  7. WiFi设备的区域性要求
  8. 腾讯安全联合成立数据安全专委会
  9. sass教程之--sass的安装
  10. 20大数据可视化工具测评