快排的改良版——内省式排序
快速排序是一种很快的算法,它平均的时间复杂度WieO(nlgn), 最坏时间复杂度为O(n^2)。但是快排有很多改良版,其中一种就是内省式的快排,在STL中的快快排使用的就是这种算法。
1.为什么需要这种算法
因为快排在面对小数组(比如大小为10的数组)且基本有序的情况下,它的表现还没插入排序要好。因为数组的基本有序,使得插入排序不用很多次的执行元素的移动,并且可以避免递归。 在SGI STL中的函数sort使用的排序算法其实就是内省式的排序算法。内省的排序算法是基于快排实现的。假设待排序的数组大小为n,去一个k值,使得k为满足2^k <= n的最大值。k为最大的递归层次、 为什么要设置最大递归层次呢? 因为快排的递归层次过深的时候,很可能会退化成O(n^2)。内省式排序使用k来控制快排的递归深度,当快排的递归深度到达k的时候选择使用heap排序。
2. 为什么不一开始就使用heap排序
heap排序在平均时间复杂度是O(nlgn),最坏情况也是O(nlgn),看起来要比快排要快。但是实际上,快排是要比heap排序要快,第一个原因是:heap排序虽然和快排在平均情况下的时间复杂度是O(nlgn),但是heap排序的时间常数要比快排的时间常数要大。第二个原因是:据统计,快排的最坏情况在是很少发生的。第三个原因是:快排能够比较好的吻合程序的空间局部性原理,因为它操作的基本都是相邻的元素(虚拟存储器的设计理论基础中就有程序的时间局部性和空间局部性),能够减少内存缺页中断的发生次数。
3.为什么要使用heap排序呢
因为在递归层次太深的时候,就意味着发生最坏情况的概率大大的提升了,这时候因为heap排序的最坏情况下的时间复杂度是O(nlgn)比快排的O(n^2)要好,因此使用heap排序能更好优化排序效率。
参考资料:《STL源码剖析》
heap排序的博文:http://blog.csdn.net/sky453589103/article/details/51211080
快速排序的博文:http://blog.csdn.net/sky453589103/article/details/51213526
快排的改良版——内省式排序相关推荐
- 【排序】快排(霍尔快排)
1.霍尔快排 int partsort1(int *a, int begin, int end)//begin,end分别为数组头尾元素下标 {int left = begin;int right = ...
- javascript 实现快排 ,三向切分快排
比如说对数组快排的思路就是: 选取一个基准(可以选数组的开头最为基准,令 i = 0 ;j = array.length -1) 从arr[j]向前遍历(j--),当该值大于基准,则交换,退出循环(b ...
- java快排原理_Java数据结构与算法——快速排序
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本篇文章介绍排序算法中最常用也是面试中最容易考到的排序算法--快排,包括快排的思 ...
- 非递归的方法写快排java_快排的最差情况以及快排平均复杂度的计算
最近突然讨论了这两个问题,有点忘记了,记录了一下网上的比较好的说法,参见Reference 快排的相关知识请参考排序总结 快排的最差情况以及如何避免 首先,快排的最差情况什么时候发生? 1. 已排序 ...
- 快速排序、快排的优化 及Java实现
一.快速排序的思想 选取一个比较的基准,将待排序数据分为独立的两个部分,左侧都是小于或等于基准,右侧都是大于或等于基准,然后分别对左侧部分和右侧部分重复前面的过程,也就是左侧部分又选择一个基准,又分为 ...
- 有苦有乐的算法 --- 随机快排
题目 使用随机快排对给定数组进行从小到大排序 [5,3,2,1,5] ⇒ [1,2,3,5,5] 解析 给定一个数组 1.在数组中找出一个数作为基准(最右侧的数2):变量l记录数组头位置,变量r记录尾 ...
- 春招冲刺Day2 [高频算法题] -- 一网打尽快排
一网打尽快排 1.初出茅庐 2.小试牛刀 3.炉火纯青(快排) 4.登峰造极(随机快排) 快速排序作为十大经典排序算法之一,在面试场中屡屡出现,不是要求手写快速排序,就是快速排序的变种,为了方便复习, ...
- 02_Python算法+数据结构笔记-冒泡排序-选择排序-插入排序-快排-二叉树
b站视频:路飞IT学城 清华计算机博士带你学习Python算法+数据结构_哔哩哔哩_bilibili 文章目录 #11 排序介绍 #12 冒泡排序介绍 #13 冒泡排序 #14 选择排序 #15 插入 ...
- 排序(下)---快排、归并
排序(下)-快排.归并 快速排序 采用分治的思想:每次选区一个数作为基准,让整个数据中凡是大于此数的放在此数的右边,小于此数的放在此数的左边,然后进行对此数的两边进行选基准,如上方式的分法,递归下去, ...
最新文章
- 最强检测 | YOLO V4?都是弟弟! CenterNet2以56.4mAP超越当前所有检测模型
- CNN 模型的参数(parameters)数量和浮点运算数量(FLOPs)是怎么计算的
- lintcode-【简单题】快乐数
- [蓝桥杯2015决赛]积分之迷-枚举(水题)
- webstrom中打包的详细_webpack打包体积优化
- C#比较两个日期的大小两种案例解析
- 和我一起开发Android应用(二)——“悦词-i背单词”项目功能分析
- Mybatis的Mapper代理
- 为什么很多创业者选择餐饮行业?
- Response.setContentType 可设置属性
- 【CSS】虎躯一震!flex=1 和 flex-grow=1 竟然不一样!
- 【翻译】CodeMix使用教程(七):扩展
- 【线上课程】4节课8小时培训,《白话区块链》作者蒋勇教你快速掌握区块链智能合约开发...
- Eclipse 快捷键
- 卢森堡携手欧洲航天局,在大公国建立独一无二的“欧洲太空资源创新中心”
- ios之Xcode6如何手动创建空工程模板
- 一张图看懂MTK 芯片命名规则
- 小程序上线发布后,实现版本自动更新,用户无感知
- Python--详解脚本语言|编译语言|胶水语言的区别
- STL常用——acwing——yxc