<算法笔记>关于快速排序的算法优化排序(顺便给百度百科纠个错)
快速排序是排序算法之中的基本中的基本,虽然越来越多的接口函数将快速排序“完美的封装了起来”,比如C++中的qsort或者<algorithm>中的sort(与stable_sort相对应),但是深入思考,关于快速排序的优化你可曾想过?:-P
(一)经典快速排序
首先我们来看一下这个百度百科之中的快速排序版本

在上面这张图中,我们一边纠错一边复习下基本的快速排序,基本快速排序的函数体可以明确分为三个块:
1.调整块,根据对称轴pivot(一般选取第一个)从数组的前后两端向中间扫描,pivot作对称轴的同时也是一个哨兵,需要先把哨兵的值保存下来然后进行调换直到完成划分。每次循环注意到左端和右端只能有一次赋值的过程。
2.3.分别向前向后递归。
int tmpL=low;
int tmpR=high;
int tmpV=arr[low];
while(tmpL<tmpR){
while(tmpL<tmpR&&arr[tmpR]<=tmpV)tmpR--;
arr[tmpL]=arr[tmpR];
while(tmpL<tmpR&&arr[tmpL>=tmpV])tmpL++;
arr[tmpR]=arr[tmpL];
}
而在我给出的百度百科的算法中首先是把pivot耿直地写成了povit(可以忽略哈哈何厚铧),然后是一个很严肃的问题,关于代码的格式,要是百科编者不屑于写这种简单的代码的话可以不写嘛,或者再动一动写个花括号也就没事了,总而言之这段代码是不可能被新手/编译器看懂的!
在基本的几种算法之中,快速排序的运行速度是最快的,但是也是不稳定的,也许有的人会说堆排序运行速度理论上不比快速排序慢,但是其实不然,这和计算机部件中cache的命中率有关,堆排序需要在也许很广的地址空间里面不停地进行随机访问。
(二)三路快速排序
三路快速排序与经典快速排序不同之处在于划分部分,也就是函数的第一块。首先我们来看一下经典快速排序的划分过程的示意图:

每一次循环的过程中会有前后两次扫描每次扫描后最多只能进行一次交换。再看三路快速排序的划分过程示意图:

三路快速排序的过程实质上也是一次两端向扫描的过程,但这是一种稳定的排序方法,其核心思想依然是“DIVIDE & CONQUER”,但是和堆排序和选择排序一样整个排序的过程是个
"整理后区"的成长过程,每次的递归过程之中我们根据当前访问到的元素和对称轴的值的比对进行三路分支:
1.当当前元素小与对称轴时,将前端标志low和当前元素进行交换,两个索引值都自加1(前端标志之前的元素都是小于对称轴的元素)
2.当当前元素大于对称轴时,将当前元素和后端标志high进行交换,只将后端标志自减1(后端标志之后的元素都是大于对称轴的元素,当前索引不变以判断这个交换过来的值应划分在哪一部分)
3.当当前元素和对称轴相等的时候,当前索引自加1
代码如下:
template<typename T> ////Operator Overriding Concerned
void tri-qsort(int low,int high,vector<T> v){
if(low>=high)return;////Recurrence Ending
else{
int tmpL=low;
int tmpR=high;
int index=low+;
int pivot=v[i]
while(index<=tmpR){
if(index<pivot) swap(v[index++],v[tmpL++]);
else if(index>pivot) swap(v[index],v[tmpR--]);
else index++;
}////Partition Complete
tri-qsort(low,lt-);
tri-qsort(gt+,hight);
}
(三)双基准快速排序算法
这个双基准快速排序是我最推荐的,虽然双基准快速排序效率在理论上和其他版本的快速排序是基本一样的,但是在处理重复数据时双基准快速排序会有独特的优越性,但是时间复杂度的变化幅度会比较大。
双基准快速排序并不是简单意义上的将整个数据割为两端,交由两个不同的pivot去处理。双基准快速排序是在三路快速排序的基础之上进行的,如下图所示:

双基准排序要做的事情从宏观上来看有两个:(前提约束对称轴1小于对称轴2)
1.整理比对称轴1小的元素到前端标记之前
2.整理比对称轴2大的元素到后端标记之后
那么中间剩下的区域就是比对称轴1大而比对称轴2小的元素,所以我们要做的事情是每次递归之前改变这段数据的对称轴(最前最后两个元素),代码如下:
template<typename T>
void dual-qsort(int low,int high,vector<T> v){
if(low>high)swap(low,high);
int pivotL=low;
int pivotR=high;
int tmpL=low;
int tmpR=high;
int index=low+;
while(index<=tmpR){
if(v[index]<pivotL)swap(v[index++],v[tmpL++]);
else if(v[index]>pivotR)swap(v[index],v[tmpR--]);
else index++;
}
swap(v[--tmpL],v[low]);
swap(v[++tmpR],v[high]);
dual-qsort(low,tmpL-,v);
dual-qsort(tmpL+,tmpR-,v);
dual-qsort(tmpR+,high,v);
}
<算法笔记>关于快速排序的算法优化排序(顺便给百度百科纠个错)的更多相关文章
- 算法笔记_015:快速排序(Java)
目录 1 问题描述 2 解决方案 2.1 快速排序原理简介 2.2 具体编码 1 问题描述 给定一组数据,使用快速排序得到这组数据的非降序排列. 2 解决方案 2.1 快速排序原理简介 引用自百度百科 ...
- C / C++算法学习笔记(8)-SHELL排序
原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...
- 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)
Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...
- 常见排序算法总结:插入排序,希尔排序,冒泡排序,快速排序,简单选择排序以及java实现
今天来总结一下常用的内部排序算法.内部排序算法们需要掌握的知识点大概有:算法的原理,算法的编码实现,算法的时空复杂度的计算和记忆,何时出现最差时间复杂度,以及是否稳定,何时不稳定. 首先来总结下常用内 ...
- javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
- 算法笔记(c++)--桶排序题目
算法笔记(c++)--桶排序 记得题目是排序,输入n个1-1000的数字然后去重然后排序. 桶排序没毛病 #include<iostream> using namespace std; i ...
- 算法笔记_023:拓扑排序(Java)
目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进 ...
- 排序算法四:快速排序(Quicksort)
快速排序(Quicksort),因其排序之快而得名,虽然Ta的平均时间复杂度也是O(nlgn),但是从后续仿真结果看,TA要比归并排序和堆排序都要快. 快速排序也用到了分治思想. (一)算法实现 pr ...
- 算法笔记_014:合并排序(Java)
1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...
随机推荐
- ElasticSearch的备份迁移方案
使用插件repository-hdfs插件进行测试 下载地址: https://oss.sonatype.org/content/repositories/snapshots/org/elastics ...
- 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...
- 内网ip打洞-----p2p实现原理
网上找了非常多.代码大堆,原理讲清楚透彻的不多. 本人找几篇讲得好的来整理一下. 一片技术文章,最基本的讲清楚原理.假设再有完整的能执行的源码也可,关键是要把核心部分代码分析清楚. (1)问题的由来: ...
- 奇怪!post提交 地址栏参数竟然可见
转: http://blog.csdn.net/yuebinghaoyuan/article/details/7727802 在做项目中,form标签中method="post&quo ...
- 【SharePoint】K2 for SharePoint 安装笔记【未完工】
0.安装环境说明 0.1.软件版本 OS : Window Server 2012 标准版 SharePoint : 2013标准版 K2 : 4.6.9 0.2.环境结构 SharePoint 20 ...
- 分享个免费的货币汇率API
先上API文档链接:https://www.juhe.cn/docs/api/id/23,支持人民币牌价.外汇汇率查询:数据仅供参考,交易时以银行柜台成交价为准. 人民币牌价 接口地址:http:// ...
- DisplayPort的时钟隐藏和时钟恢复
转:DisplayPort的时钟隐藏和时钟恢复 无时钟线的视频数据传输是DP协议的一大特点,将时钟信号隐藏在数据中是传输协议的设计趋势.时钟恢复技术也是DP芯片设计的关键技术.在这说一下在发送端时钟是 ...
- 六种基本DCDC变换器拓扑结构
1.SEPIC电路 2.
- 关于cocos2d-x 和安卓之间的相互调用
近期在研究cocos2d游戏移植安卓须要调用非常多方法.所以在研究之中写下它们之间相互调用 首先,cocos2d调用安卓 在一个.h文件里加入头文件 #include <jni.h> #i ...
- 最短路 uva12661 Funny Car Racing
传送门:点击打开链接 题意:给你有向图,每条边呈周期性开放,即开放a时间,再关闭b时间.再开放a时间以此类推 假设时间不足以穿过这条路则不能走.你能够在节点等待时间,问从s走到t所须要的最小时间 细致 ...