快速排序基本思想是,对待排序序列进行划分(Partition),一次划分,选择一个元素作为枢轴,然后将所有比枢轴小的元素放到枢轴的左边,将比枢轴大的元素放到枢轴的右边。然后对该枢轴划分的左右子序列分别再进行划分,如此递归。Partition是一个非常重要的概念,因为它只需要O(n)的时间复杂度就可以将待排序序列划分为两块具有大小关系的区间,可以根据这一特性求解待排序序列中最大的k个数、第k大的数等类似问题。

  快速排序算法复杂度O(nlogn).

  就平均时间而言,快速排序是目前被认为是最好的一种内部排序方法,其平均时间是O(nlogn),最坏情况是O(n^2),最坏的情况就是如下倒序完后再正序排的情况。

  C++代码如下:

#include "stdafx.h"

#define MAXSIZE 20

typedef struct{
int r[MAXSIZE+];
int len;
}SqList; int Partition(SqList &L, int low, int high)
{
L.r[] = L.r[low]; // 以第一个元素作为枢轴
int pivotkey = L.r[low];// 记录枢轴关键字
while (low < high)
{
while(low<high && L.r[high]>=pivotkey)
      --high;// 找到从high位置开始向前第一个比枢轴小的元素
L.r[low] = L.r[high];// 将找到的比枢轴小的元素放到前边的空闲位置
while(low<high && L.r[low]<=pivotkey)
      ++low;// 找到从low位置开始向后第一个比枢轴大的元素
L.r[high] = L.r[low];// 将找到的比枢轴大的元素放到后边的空闲位置
}
L.r[low] = L.r[];// 将枢轴放回中间的空闲位置,由while{}循环可知,low最后空闲 return low;
} void QSort(SqList &L, int low, int high)
{
if (low < high)
{
int pivotloc = Partition(L, low, high);
QSort(L, low, pivotloc-);
QSort(L, pivotloc+, high);
}
} int _tmain(int argc, _TCHAR* argv[])
{
SqList sqList;
for (int i=; i<MAXSIZE+; i++)
{
sqList.r[i] = MAXSIZE - i;
}
sqList.len = MAXSIZE; QSort(sqList, , sqList.len); return ;
}
// 附一次划分过程,第一行为index,第二行为待排序序列
// 0 1 2 3 4 5 6 7
// __ 49 38 65 97 76 13 27 // 开始时,0号位空闲(low:1, high:7)
// 49 __ 38 65 97 76 13 27 // 将第1号元素作为枢轴,放到0号位,1号位冗余(low:1, high:7)
// 49 27 38 65 97 76 13 __ // 发现27比49小,将7号位值放到1号位,7号位冗余(low:1, high:7)
// 49 27 38 __ 97 76 13 65 // 发现65比49大,将3号位值放到7号位,3号位冗余(low:3, high:7)
// 49 27 38 13 97 76 __ 65 // 发现13比49小,将6号位值放到3号位,6号位冗余(low:3, high:6)
// 49 27 38 13 __ 76 97 65 // 发现97比49大,将4号位值放到6号位,4号位冗余(low:4, high:5)
// __ 27 38 13 49 76 97 65 // low == high,将枢轴放到4号位,此时49左边的都比49小,右边的都比49大

  STL的所有关系型容器都拥有自动排序的功能(底层采用RB-tree),所以不需要sort算法。序列式容器的中的stack、queue等都有特别的出入口,不允许用户对元素进行排序。剩下的vector、deque和list,前两者的迭代器属于RandomAccessIterators,适合sort算法。泛型算法一定要求迭代器是RandomAccessIterators。因为任何一个元素都可以被选作枢轴(pivot),但是其合适与否却会影响Quick Sort的效率。为了避免枢轴不够随机带来的恶化效应,最理想的方式是取整个序列的头、尾、中央三个位置的元素,以其中值作为枢轴,这种做法成为三点中值(Median-of-Three),为了能够快速取出中央位置的元素,显然迭代器必须能够随机定位,因此快速排序的泛型算法中迭代器必须是RandomAccessIterators。

  STL的sort算法,数据量大时采用Quick Sort,分段递归排序。一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负担,就改用Insertion Sort。Insertion Sort虽然时间复杂度是O(n^2),但是当数据量很小时,却有不错的效果。另外虽然STL有三点中值来防止枢轴选取不当的问题,还有introsort进行自我侦测,如果分割行为有恶化倾向时,会转而改用Heap Sort。

  

快速排序及STL中的sort算法的更多相关文章

  1. STL中的排序算法

    本文转自:STL中的排序算法 1. 所有STL sort算法函数的名字列表: 函数名    功能描述 sort   对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 ...

  2. STL中的所有算法(70个)

    STL中的所有算法(70个)----9种类型(略有修改by crazyhacking) 参考自: http://www.cppblog.com/mzty/archive/2007/03/14/1981 ...

  3. 为什么map对象不能使用stl中的sort函数

    STL所提供的各式各样算法中,sort()是最复杂最庞大的一个.这个算法接受两个RandomAccestlerators(随机存取迭代器),然后将区间内的所有元素以渐增方式由小到大重新排列.第二个版本 ...

  4. STL中的查找算法

    STL中有很多算法,这些算法可以用到一个或多个STL容器(因为STL的一个设计思想是将算法和容器进行分离),也可以用到非容器序列比如数组中.众多算法中,查找算法是应用最为普遍的一类. 单个元素查找 1 ...

  5. STL中主要的算法(一)

    一.replace() 替换算法将指定元素值替换为新值,使用原型例如以下,将迭代器[first,last)中值为old_value的元素所有替换为new_value值. 函数原型: template  ...

  6. 【决战西二旗】|理解Sort算法

    前言 前面两篇文章介绍了快速排序的基础知识和优化方向,今天来看一下STL中的sort算法的底层实现和代码技巧. 众所周知STL是借助于模板化来支撑数据结构和算法的通用化,通用化对于C++使用者来说已经 ...

  7. STL中的算法

    STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baidu.com/ding ...

  8. STL中vector的赋值,遍历,查找,删除,自定义排序——sort,push_back,find,erase

    今天学习网络编程,那个程序中利用了STL中的sort,push_back,erase,自己没有接触过,今天学习一下,写了一个简单的学习程序.编译环境是VC6.0         这个程序使用了vect ...

  9. STL中sort、priority_queue、map、set的自定义比较函数

    STL中,sort的默认排序为less,也就是说从小到大排序:priority_queue默认是less,也就说大顶堆:map默认是less,也就说用迭代器迭代的时候默认是小的排在前面:set默认是l ...

随机推荐

  1. Luogu2483 [SDOI2010]魔法猪学院(可并堆)

    俞鼎力大牛的课件 对于原图以 \(t\) 为根建出任意一棵最短路径树 \(T\),即反着从 \(t\) 跑出到所有点的最短路 \(dis\) 它有一些性质: 性质1: 对于一条 \(s\) 到 \(t ...

  2. gulp & webpack整合

    为什么需要前端工程化? 前端工程化的意义在于让前端这个行业由野蛮时代进化为正规军时代,近年来很多相关的工具和概念诞生.好奇心日报在进行前端工程化的过程中,主要的挑战在于解决如下问题:✦ 如何管理多个项 ...

  3. SpringBoot 整合 Mybatis + Mysql——XML配置方式

    一.介绍 SpringBoot有两种方法与数据库建立连接,一种是集成Mybatis,另一种用JdbcTemplate,本文主要讨论集成Mybatis方式. SpringBoot整合Mybatis也有两 ...

  4. 手动替换WORDPRESS的GOOGLE字体等加速【非插件】

    手动替换WORDPRESS的GOOGLE字体等加速[非插件] 179 看过 | 2015年3月4日 | Linux, 随意Coding | 暂无评论 查找需要替换的地方 Linux下,在网站文件夹中, ...

  5. 应用程序 调用 webservice

    首先用VS创建一个WebService服务工程,并且完成基本功能,本人完成的是html转pdf功能. 然后,新建一个Windows应用程序. 添加WebService到Windows项目中,如图 然后 ...

  6. axios 同步问题

    Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中(这是官方文档给出的一个解释说明) 它的主要作用是向后台发起异步请求,还有在请求中做更多的可控功能 1. ...

  7. 如何用kindle看论文

    kindle的pdf显示效果向来不好,那么如何把pdf转换成mobi格式呢 可以把个人文件(pdf)发送至您的[发送至Kindle]电子邮箱时,在电子邮件的主题栏中填写"convert&qu ...

  8. JAVA后台框架优化之日志篇

    1.日志规范 各业务系统日志需要统一,以方便查看.收集日志, 日后统一ELK日志管理,以下为项目的日志配置, 这是兼容当前系统的日志,以后推行微服架构时会有变动,但日志存放方式不会改变,日后会推行sp ...

  9. Hbase集群部署

    1.安装Hadoop集群 这个之前已经写过 2.安装Zookeeper 这个之前也已经写过 3.下载hbase,放到master机器,解压 4.修改hbase-env.sh,添加Java地址 expo ...

  10. AD账户锁定策略

    AD账户锁定策略在一个域中可以有多套,密码策略只能有一套