快速排序基本思想是,对待排序序列进行划分(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. Ajax 之XMLHttpRequest讲解

    一直以来都听别人说Ajax,今天终于接触到了.......... 一.什么是Ajax? 答: AJAX即“Asynchronous Javascript And XML”(异步JavaScript和X ...

  2. Angular进阶教程三

    7 总结 angular上手比较难,初学者(特别是习惯了使用JQuery的人)可能不太适应其语法以及思想.随着对ng探索的一步步深入,也确实感觉到了这一点,尤其是框架内部的某些执行机制. 7.1页面效 ...

  3. JS判断客户端是手机还是PC的2个代码

    搬了下砖 function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", & ...

  4. redis在windows上安装+RedisDesktopManager

    redis我就不在这里介绍了,这里直接介绍windows安装redis服务,网上有很多介绍windows版,我这边安装的是一个极简版的. redis官方下载地址:https://redis.io/do ...

  5. 毕向东_Java基础视频教程第20天_IO流(5~6)

    第20天-05-IO流(文件列表一) static File[] listRoots() List the available filesystem roots. String[] list() Re ...

  6. 两种开源聊天机器人的性能测试(二)——基于tensorflow的chatbot

    http://blog.csdn.net/hfutdog/article/details/78155676 开源项目链接:https://github.com/dennybritz/chatbot-r ...

  7. 打通版微社区(6):部署微信插件及开通QQ云服务

    写在前面: 此文是我最后写的.其实实际部署的时候,我是先安装了论坛并试图开通微信的微社区.发现微社区需要在微信公众平台的开发者中心里配置 "网页账号,网页授权获取用户基本信息"为论 ...

  8. 数据库相关文章转载(2) MySQL自带的性能压力测试工具mysqlslap详解

    PS:今天一同事问我有木有比较靠谱的mysql压力测试工具可用.其实mysql自带就有一个叫mysqlslap的压力测试工具,还是模拟的不错的.下面举例说说.mysqlslap是从5.1.4版开始的一 ...

  9. [EffectiveC++]item06:若不想使用编译器自动生成的函数,就该明确决绝

  10. [COGS 0107][NOIP 2003] 传染病控制

    107. [NOIP2003] 传染病控制 ★★★   输入文件:epidemic.in   输出文件:epidemic.out   简单对比时间限制:1 s   内存限制:128 MB [问题背景] ...