当前位置:网站首页>快速排序
快速排序
2022-08-02 14:11:00 【海无垠】
public void quickSort(int[] arr, int begin, int end) { //如果区间不只一个数 if (begin < end) { int temp = arr[begin]; //将区间的第一个数作为基准数 int i = begin; //从左到右进行查找时的“指针”,指示当前左位置 int j = end; //从右到左进行查找时的“指针”,指示当前右位置 //不重复遍历 while (i < j) { //当右边的数大于基准数时,略过,继续向左查找 // 不满足条件时跳出循环,此时的j对应的元素是小于基准元素的 while (i < j && arr[j] > temp) j--; if (i < j)//将右边小于等于基准元素的数填入右边相应位置 arr[i] = arr[j]; //当左边的数小于等于基准数时,略过,继续向右查找 //(重复的基准元素集合到左区间) //不满足条件时跳出循环,此时的i对应的元素是大于等于基准元素的 while (i < j && arr[i] <= temp) i++; //将左边大于基准元素的数填入左边相应位置 if (i < j) arr[j] = arr[i]; } //将基准元素填入相应位置 arr[i] = temp; //此时的i即为基准元素的位置 //对基准元素的左边子区间进行相似的快速排序 quickSort(arr, begin, i - 1); //对基准元素的右边子区间进行相似的快速排序 quickSort(arr, i + 1, end); } //如果区间只有一个数,则返回 else return; }
时间复杂度
快速排序涉及到递归调用,所以该算法的时间复杂度还需要从递归算法的复杂度开始说起;
递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n) ;对于递归算法的时间复杂度这里就不展开来说了;
最优情况下时间复杂度
快速排序最优的情况就是每一次取到的元素都刚好平分整个数组(很显然我上面的不是);
此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间;
下面来推算下,在最优的情况下快速排序时间复杂度的计算(用迭代法):
T[n] = 2T[n/2] + n ----------------第一次递归
令:n = n/2 = 2 { 2 T[n/4] + (n/2) } + n ----------------第二次递归
= 2^2 T[ n/ (2^2) ] + 2n
令:n = n/(2^2) = 2^2 { 2 T[n/ (2^3) ] + n/(2^2)} + 2n ----------------第三次递归
= 2^3 T[ n/ (2^3) ] + 3n
......................................................................................
令:n = n/( 2^(m-1) ) = 2^m T[1] + mn ----------------第m次递归(m次后结束)
当最后平分的不能再平分时,也就是说把公式一直往下跌倒,到最后得到T[1]时,说明这个公式已经迭代完了(T[1]是常量了)。
得到:T[n/ (2^m) ] = T[1] ===>> n = 2^m ====>> m = logn;
T[n] = 2^m T[1] + mn ;其中m = logn;
T[n] = 2^(logn) T[1] + nlogn = n T[1] + nlogn = n + nlogn ;其中n为元素个数
又因为当n >= 2时:nlogn >= n (也就是logn > 1),所以取后面的 nlogn;
综上所述:快速排序最优的情况下时间复杂度为:O( nlogn )
最差情况下时间复杂度
最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序)
这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n] = n * (n-1) = n^2 + n;
综上所述:快速排序最差的情况下时间复杂度为:O( n^2 )
平均时间复杂度
快速排序的平均时间复杂度也是:O(nlogn)
空间复杂度
其实这个空间复杂度不太好计算,因为有的人使用的是非就地排序,那样就不好计算了(因为有的人用到了辅助数组,所以这就要计算到你的元素个数了);我就分析下就地快速排序的空间复杂度吧;
首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况
边栏推荐
- 总结计算机网络超全面试题
- 背包问题-动态规划-理论篇
- 【系统设计与实现】基于flink的分心驾驶预测与数据分析系统
- Doubled and sparse tables
- Masters and Masters
- How to solve Win11 without local users and groups
- yolov5官方代码解读——前向传播
- Based on the matrix calculation in the linear regression equation of the coefficient estimates
- 用U盘怎么重装Win7系统?如何使用u盘重装系统win7?
- 二叉排序树与 set、map
猜你喜欢
Mysql之MVCC
How to reinstall Win7 system with U disk?How to reinstall win7 using u disk?
Installation and configuration of Spark and related ecological components - quick recall
Based on the least squares linear regression equation coefficient estimation
C语言函数参数传递模式入门详解
Codeforces Round #605 (Div. 3)
推开机电的大门《电路》(三):说说不一样的电阻与电导
cmake配置libtorch报错Failed to compute shorthash for libnvrtc.so
如何用硬币模拟1/3的概率,以及任意概率?
Mysql lock
随机推荐
二叉树遍历之后序遍历(非递归、递归)入门详解
KiCad常用快捷键
项目:数据库表的梳理
动态数组-vector
Doubled and sparse tables
使用libcurl将Opencv Mat的图像上传到文件服务器,基于post请求和ftp协议两种方法
IPV4和IPV6是什么?
Fast advanced TypeScript
Please make sure you have the correct access rights and the repository exists. Problem solved
Win11电脑一段时间不操作就断网怎么解决
Detailed explanation of Golang garbage collection mechanism
为vscode配置clangd
推开机电的大门《电路》(二):功率计算与判断
LeetCode 2353. 设计食物评分系统 维护哈希表+set
STM32LL library - USART interrupt to receive variable length information
MATLAB绘图命令fimplicit绘制隐函数图形入门详解
pytorch模型转libtorch和onnx格式的通用代码
Cmd Markdown 公式指导手册
Mysql lock
MATLAB图形加标注的基本方法入门简介