快速排序入门(动图演示)
快速排序时间复杂度是O(nlogn)
快速排序思路
(整个图大概有六七分钟,完整的演示了快速排序的全部内容)
下面给出一次快速排序的思路:
排序主要思想就是twoPointers 思想(twoPointers是什么?)
①定义两个变量 i 和 j分别指向待排序数组的首尾,定义一个临时变量temp存储 i 指向的元素内容(一次排序目的就是令temp在序列中寻找一个合适的位置,使temp左侧元素都不超过temp,右侧的元素都大于temp)
②令 j 不断向左移动,直到找到某一元素A[ j ] <= 该元素,然后将它挪到A[ i ]所在位置(A[ i ]处的元素已经保存在了temp中),j 进入等待状态, 进入③
③令 i 不断向右移动, 直到某一元素值A[ i ] > 该元素, 将A[ i ]挪到A[ j ]所在位置(原来的元素已经挪到了该去的地方), i 进入等待状态, 进入②
④ ②③不断循环,当i 和 j 指向同一个位置时该位置就是temp应该插入的位置,直接插入就行了(原来的元素已经挪到了该去的地方)
好了,现在temp左侧的元素一定不大于它,temp右侧的元素一定大于它,等于说当整个数组全部排好序后temp的位置就在这里
下面进行[ 0, temp-1 ] 和 [temp+1, n-1]位置元素的排序,方法和上面的相同,然后再不断的切割不断地排序,直到某一区间仅有一个元素为止,这就要用到递归了
下面给出一次排序的代码
int Partition(int A[], int left, int right)
{int temp = A[left];while(left < right){while(temp < A[right] && left < right) right--;A[left] = A[right];while(temp >= A[left] && left < right) left++;A[right] = A[left];}A[left] = temp;return left;
}
有了一次排序后我们就可以递归进行多次排序
void QuickSOrt(int A[], int left, int right)
{if(left < right){int pos = Partition(A, left, right);QuickSOrt(A, left, pos-1);QuickSOrt(A, pos+1, right);}
}
下面是完整代码
#include <iostream>
#include<cstdio>
using namespace std;int Partition(int A[], int left, int right)
{int temp = A[left];while(left < right){while(temp < A[right] && left < right) right--;A[left] = A[right];while(temp >= A[left] && left < right) left++;A[right] = A[left];}A[left] = temp;return left;
}void QuickSOrt(int A[], int left, int right)
{if(left < right){int pos = Partition(A, left, right);QuickSOrt(A, left, pos-1);QuickSOrt(A, pos+1, right);}}int main()
{int A[11] = {35,18,16,72,24,65,12,88,46,28,55};QuickSOrt(A, 0, 10);for(int i = 0; i< 11; i++){printf("%d ", A[i]);}return 0;
}
输出:
快速排序优化
快速排序的特点是元素的排列越随机(不按顺序的程度高)效率越高,但序列中元素接近有序时会达到最坏的时间复杂度O(n2),原因在于我们总令temp是待排区间最左侧的元素,比如1 2 3 5 4,我们取到了1,它左边没区间,右边区间只减少了1
优化的具体做法是尽可能的令temp在区间内随机取值,这样,该算法的数学期望就稳定在O(nlogn) (详细证明见《算法导论》)
c语言中有个随机数生成器,它的写法具体是这样的:
#include<cstdio>
#include<cstdlib>
#include<ctime>
...
void _rand()
{srand((unsigned) time(NULL)); //随机数生成器必备语句for(int i = 0; i< 10; i++)printf("%d ", rand()); //rand()生成随机数printf("\nRAND_MAX = %d", RAND_MAX); // 生成最大值
}
输出结果
它输出最大值为32767,如果我们想令它生成范围在[a , b]之间该怎么办呢?
rand() % (b-a+1) => 输出区间在[0, b-a]之间,再 +a 就是区间[a , b]了, 即
rand() % (b-a +1) + a
如果想生成大于32767的区间该怎么办呢?
一种方法是:rand() / RAND_MAX 生成[0 , 1]的浮点数,再乘(b-a)+ a即可
(int)(round(1.0*rand() / RAND_MAX * (b-a)+a))
回到快速排序上
我们要做的是令待排序元素temp在[ i, j ]中随机取,不要忘记,已经排序好的元素时不会出现在区间内的,所以我们取一个随机元素A[p], 让它和A[ i ] 交换即可,没有任何影响。而且temp变量还可以 = A[ i ],前面的代码不会发生变化
int randPartition(int A[], int left, int right)
{//变化开始处srand((unsigned)time(NULL));int p = 1.0*rand() / RAND_MAX*(right-left) +left;swap(A[left], A[p]);//变化终止处int temp = A[left];while(left < right){while(temp < A[right] && left < right) right--;A[left] = A[right];while(temp >= A[left] && left < right) left++;A[right] = A[left];}A[left] = temp;return left;
}
输出结果相同
over
快速排序入门(动图演示)相关推荐
- 十大经典排序算法Python版实现(附动图演示)
来源:大数据DT 本文约5200字,建议阅读10分钟 排序算法是<数据结构与算法>中最基本的算法之一.本文介绍10种常见的内部排序算法,及如何用Python实现. 排序算法可以分为内部排序 ...
- 一文读懂Python版的十大经典排序算法(附动图演示)
来源:大数据DT 本文约5200字,建议阅读10分钟 排序算法是<数据结构与算法>中最基本的算法之一.本文介绍10种常见的内部排序算法,及如何用Python实现. 排序算法可以分为内部排序 ...
- 数据结构与算法--经典10大排序算法(动图演示)【建议收藏】
十大经典排序算法总结(动图演示) 算法分类 十大常见排序算法可分为两大类: 比较排序算法:通过比较来决定元素的位置,由于时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序 非比较类型排 ...
- 十大经典排序算法(动图演示,收藏好文)
0.算法概述 0.1 算法分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线 ...
- 十大经典排序C++实现及动图演示
0.算法概述 0.1 算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序: ...
- c 语言从大到小排序算法,10 大经典排序算法(动图演示+ C 语言代码)
原标题:10 大经典排序算法(动图演示+ C 语言代码) 来源:C语言与CPP编程 以前也零零碎碎发过一些排序算法,但排版都不太好,又重新整理一次,排序算法是数据结构的重要部分,系统地学习很有必要. ...
- 程序员面试必备:动图演示十大经典排序算法及代码实现
0.算法概述 0.1 算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序: ...
- 十大经典排序算法(动图演示)(转)
十大经典排序算法(动图演示) 本文转自https://www.cnblogs.com/onepixel/articles/7674659.html 0.算法概述 0.1 算法分类 十种常见排序算法可以 ...
- 一文总结十大经典排序算法(思维导图 + 动图演示 + 代码实现 C/C++/Python + 致命吐槽)
声明 1)该文章整理自网上的大牛和专家无私奉献的资料,具体引用的资料请看参考文献. 2)本文仅供学术交流,非商用.如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除. 3)博主才疏学浅,文中如 ...
- 算法 - 十大经典排序算法(动图演示)
[TOC] 算法 - 十大经典排序算法(动图演示) 在计算机科学与数学中,一个排序算法(英语:Sorting algorithm)是一种能将一串资料依照特定排序方式进行排列的一种算法.最常用到的排 ...
最新文章
- Loadrunner 性能测试服务器监控指标
- centos mate桌面_CentOS 7安装桌面汇总
- Spring和SpringMVC的区别
- 对话李飞飞,揭秘国际体育赛事风“云”背后的黑科技
- DP备份任务失败原因解析
- html打印边距影响内容大小,关于web打印的问题,如何控制纸张大小和页边距
- mysql 其他引擎
- Python 03 基础作业
- 北大FAIR自动化所快手提出基于动量对比学习的层次Transformer—HiT,用于视频文本检索!代码已开源!...
- ihtml2document能不能根据id获取dom_JavaScript学习笔记(十三)-- DOM(上)
- 7.数据对象映射模式
- “学霸系统”课堂展示
- 基于MATLAB的极限与求导(附完整代码)
- 在路上——黄山、宏村
- 就北京来说,有对 PM2.5 有用的空气净化器么?
- 电压源和电流源的区别
- 2021年阿里巴巴Java岗位面试(已拿offer)
- 【经验】经验总结-经验教训
- 计算机数值方法知识,计算机数值方法.pdf
- 冲量在线要做数据流通基础设施服务商
热门文章
- Python3写爬虫(五)爬取糗事百科段子
- DeepFM模型调参
- 解决Linux服务器执行出现 -bash: ./xxx.sh: /bin/sh^M: bad interpreter: No such file or directory
- 大学毕业后很迷茫不知道干什么?看完这几点你就知道了
- java 苹果内支付_一款集成支付宝、微信支付的Java源码,支持安卓、苹果,maven项目可以看看。申精...
- 影响神经网络训练速度的因素使得神经网络训练速度加快的方法
- 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
- 如何优雅的对 Docker 容器进行健康检查
- 数据结构之栈 篇四——栈应用实现进制转换
- 如何提升应届生职场竞争力