快速排序(Quick Sort)—挖坑填数法
前面的博文讲了冒泡排序、选择排序、插入排序,今天我们谈谈快速排序!
快速排序的基本思想是:
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)—挖坑填数法相关推荐
- 一次partition过程一(挖坑填数法)
题目描述 快排的关键在于划分(partition操作),一次划分过程有很多实现的思路.请对a[1].a[2].....a[n]实现一次partition,并输出结果. 要求:使用"挖坑法&q ...
- 一头扎进算法导论-快速排序(挖坑填数策略)
定义:它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到 ...
- 数据结构-挖坑填数+分治法解决快速排序问题(java+c)
文章目录 一.定义 1.分治法 2.挖坑填数 3.快速排序思想 二.代码实例 1.Java 2.c语言 看到网上有很多的讲解,决定自己整理一遍 首先上定义 一.定义 1.分治法 分治算法的基本思想是将 ...
- 快速排序 Quick Sort
快速排序 Quick Sort 我们已经知道,在决策树计算模型下,任何一个基于比较来确定两个元素相对位置的排序算法需要Ω(nlogn)计算时间.如果我们能设计一个需要O(n1ogn)时间的排序算法,则 ...
- 快速排序 (Quick Sort)(Java实现)
快速排序(Quicksort)是对冒泡排序的一种改进,借用了分治的思想,由C. A. R. Hoare在1962年提出. 1.基本思想 快速排序的基本思想:挖坑填数+分治法. 首先选一个轴值(pivo ...
- 【排序算法】快速排序(Quick Sort)
快速排序(Quick Sort)使用分治法算法思想. 快速排序介绍 它的基本思想是: 选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小. ...
- Golang TDD实践报告:快速排序Quick Sort
Golang TDD实践报告:快速排序Quick Sort [阅读时间:约5分钟] 0.项目需求 1.编写符合项目输入输出的一个测试 2.尝试运行测试 3.先使用最少的代码来让失败的测试先跑起来 4. ...
- C语言快速排序 quick sort 算法(附完整源码)
快速排序 quick sort 算法 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) # ...
- 奇数幻方的经典解决方法--右上方填数法
幻方,也教纵横图,就是在n×n的方阵中放入1到n 2个自然数:在一定的布局下,其各行.各列和两条对角线上的数字之和正好都相等.这个和数就叫做"幻方常数"或幻和. 构造幻方的方法: ...
最新文章
- 2018-07-12 第六十七天 EsayUI
- Oracle Net Configuration(监听程序和网络服务配置)
- 【研发管理】结构化流程框架
- linux echo写php编码,linux使用和基础操作(示例代码)
- 单例模式——Java
- java socket优化_Java Socket编程代码优化
- AlertDialog禁止返回键
- 10打开没有反应_118个遇水反应化学品清单及高压反应釜操作经验
- getHibernateTemplate()为NUll
- sping 总结(03)springmvc
- mysql5.7.11源码安装_centos 7.0安装MySQL Community Server 5.7.11 源码编译安装
- 如何创建PDF格式文件,这个方法教你快速创建
- 雨滴win7计算机路径,Rainmeter雨滴桌面Win7打不开怎么办?
- 彻底解决tplink路由器无法访问部分https网站
- MD5值的简介和查看
- 谷歌浏览器翻译插件方便阅读方法,收藏备用
- Google Maps JavaScript API 使用
- [android][马达]振动反馈-转子马达效果参数配置
- 利用CRM客户管理系统抓住销售商机
- 2023 年 4 月脚本神器合集来了