最近突然讨论了这两个问题,有点忘记了,记录了一下网上的比较好的说法,参见Reference

快排的相关知识请参考排序总结

快排的最差情况以及如何避免

首先,快排的最差情况什么时候发生?

1. 已排序

2. 数值全部相等(1的特殊情况)

快排最好的情况是,每次正好中分,复杂度为O(nlogn)。最差情况,复杂度为O(n^2),退化成冒泡排序

为了尽量避免最差情况的发生,就要尽量使每次选择的pivot为中位数。

一般常用的方法是,对每一个数列都取一次中位数(O(n)),这样总体的快排时间复杂度仍为O(nlogn)。

更为简化的方法是,取头、中、尾的中位数(O(1))作为pivot

另一个问题:

如果有元素等于pivot,是换还是不换呢?

1. 如果换,那当遇到全是一样的数,每一次都要交换,但是有一个好处是,pivot会移动到中间的地方,正好中分,符合快排最好的情况,复杂度为O(nlogn)

2. 如果不换,同样是全是一样的数,的确不用交换,i指针一直移到最后遇到j指针,pivot被移动到最后一位。分治时,右边没有元素,左边n-1个元素,重复一下。符合快排最坏情况,复杂度为O(n^2)

综上,还是换吧。

对于最差情况的第2种数据,即数值全部相等,或者存在大量相等的数值时,Java的sort方法中使用三向切分快排来优化这个问题,详情请看Java中的排序

快排平时时间复杂度计算

计算方式来源于算法导论

主定理: T [n] = aT[n/b] + f (n)

其中 a >= 1 and b > 1 是常量 并且 f (n) 是一个渐近正函数, 为了使用这个主定理,您需要考虑下列三种情况:

快速排序的每一次划分把一个 问题分解成两个子问题,其中的关系可以用下式表示:

T[n] = 2T[n/2] + O(n) 其中O(n)为PARTITION()的时间复杂度,对比主定理,

T [n] = aT[n/b] + f (n)

我们的快速排序中:a = 2, b = 2, f(n) = O(n)

Reference:

1. https://www.geeksforgeeks.org/when-does-the-worst-case-of-quicksort-occur/

2.《算法导论》

非递归的方法写快排java_快排的最差情况以及快排平均复杂度的计算相关推荐

  1. 编写函数 int fac(int x)计算 x!的值。在主函数中输入 n 和 m 的值,通过调用函数 fac 计算m Cn 的值(要求分别用递归和非递归的方法编写函数 fac)

    编写函数 int fac(int x)计算 x!的值.在主函数中输入 n 和 m 的值,通过调用函数 fac 计算m Cn 的值(要求分别用递归和非递归的方法编写函数 fac) 递归: #includ ...

  2. 用递归和非递归的方法求解n的k次方

    递归的方法 #include<stdio.h>int my_power(int n,int k) {if (k-- > 1)n*=my_power(n, k);return n; } ...

  3. 完全二叉树的JAVA实现(以及非递归遍历方法)

    一个用于实现初始化指定个数的完全二叉树,以及两个非递归的深度优先遍历,和广度优先遍历 package fifth; import java.util.Random; public class Tool ...

  4. 数据结构:利用栈,将递归转换为非递归的方法

    利用栈将递归转换为非递归 对于一般的递归过程,仿照递归算法执行过程中递归工作栈的状态变化,可直接写出相应的非递归算法. 步骤 第一次调用的参数push进堆栈,原有递归代码外层加一个while循环,判断 ...

  5. 利用栈将递归转换为非递归的方法

    通过上述讨论,可以看出递归程序在执行时需要系统提供隐式栈这种数据结构来实现,对于 一般的递归过程,仿照递归算法执行过程中递归工作栈的状态变化可直接写出相应的非递归算法. 这种利用栈消除递归过程的步骤如 ...

  6. 【树】二叉树的两种非递归遍历方法

    非递归的遍历需要使用栈保存当前不输出的结点,并且三种遍历顺序步骤有所不同. 中序遍历 1.查看其当前结点是否为空: 若非空则将当前结点入栈,指针指向其左孩子: 若当前结点为空,说明上一个入栈的结点没有 ...

  7. 实验六(函数) 2.编写函数 int fac(int x)计算 x!的值。在主函数中输入 n 和 m 的值,通过调用函数 fac 计算Cnm 的值(要求分别用递归和非递归的方法编写函数 fac)。

    (Cnm是m在上n在下) 非递归法: #include<stdio.h>long fac(long);int main(){long m,n,a=1,b;scanf("%ld%l ...

  8. 【数据结构与算法】八大排序(中)快速排序 快排居然还能这么优化?快排的非递归该如何写?

  9. 【转】更简单的非递归遍历二叉树的方法

    [转]更简单的非递归遍历二叉树的方法 解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出 ...

最新文章

  1. Oracle进阶学习之创建dblink
  2. “蓝桥杯”软件大赛入门训练4道题
  3. C# hashtable
  4. Redis 错误1067:进程意外终止,Redis不能启动,Redis启动不了
  5. 惠新宸php教程_惠新宸:PHP在百度的应用现状及展望
  6. okhttp 工具类_日语学习工具推荐,小白必备!
  7. Win7系统网页视频无法播放怎么办
  8. Qt简单的解析Json数据例子(一)
  9. Github Page 绑定域名
  10. ceph搭建_【实战演练】基于各种存储模拟器与软件存储的存储实验07-Ceph分布式存储的3种存储类型使用方法...
  11. FPGA入门之一位全加器的实现
  12. .NET单元测试(四):用例设计
  13. java连接mysql数据库实现图书馆管理系统
  14. Feed流及其常见算法简介
  15. 如何更换AirTag电池?
  16. linux用户无法接收邮件,linux 下 搭建邮件邮件服务器(Postfix+Dovecot)(一)-系统账户登陆收发邮件...
  17. 高三计算机教学计划,高三信息技术上册教学计划参考
  18. 爬取软科中国最好大学排名
  19. 质因子分解(Java)
  20. 计算机软件比赛团队名称,代表团队名称

热门文章

  1. centos7安装xterm_CentOS 7使用x-manager中Xstart工具报缺少xterm包错误
  2. python3l下载_lunix 安装python3
  3. python优先级排序_python中使用优先队列
  4. html 流程控制,HTML5独家分享:原生JS学习笔记2——程序流程控制
  5. java 多线程 选择题_Java多线程之三道多线程练习题
  6. 如何在Timeline中创建自定义轨道?
  7. android 控制流混淆 反向,AST混淆实战:仿obfuscator混淆控制流平坦化
  8. mysql 主键溢出检查_详解MySQL 表中非主键列溢出情况监控
  9. OpenShift 4 之 Image Registry、Image 和 ImageStream 概念和相关操作
  10. 使用C#和ASP.NET Core的PayPal智能按钮的客户端/服务器实现