STL 排序(转载)

这篇文章关于STL中的排序写的虽不深入,但是还是挺好的。

1、sort

sort有两种形式,第一种形式有两个迭代器参数,构成一个前开后闭的区间,按照元素的 less 关系排序;第二种形式多加一个指定排序准则的谓词。sort基本是最通用的排序函数,它使用快速排序算法,并且在递归过程中,当元素数目小于一个阈值(一般是16,我的试验是24)时,转成直接插入排序。伟大的数学家Knuth已经证明,在平均意义上,快速排序是最快的了;当然,最坏复杂性比较差。sort要求随机迭代器,因此对于很多编译器来说,对于前向迭代器(如list)使用sort是一个编译错误。

sort的基本使用方式如下:

 1 #include <vector>
 2 #include <algorithm>
 3 #include <functional>
 4 #include <cstdlib>
 5
 6 using namespace std;
 7
 8 void func1()
 9 {
10     vector<int> ar;
11     //向数组里面插入一些随机数
12     generate_n(back_inserter(ar), 100, rand);
13     //按从小到大排序
14     sort(ar.begin(), ar.end());
15 }

逆序排列的方法

 1 void func2()
 2 {
 3     vector<int> ar;
 4     //向数组里面插入一些随机数
 5     generate_n(back_inserter(ar), 100, rand);
 6
 7     //方法1:使用函数作为谓词
 8     sort(ar.begin(), ar.end(), GreateThan);
 9     //方法2:使用仿函数作为谓词
10     //注意下面两种方法都需要有个括号,实际上是要产生一个临时对象
11     sort(ar.begin(), ar.end(), CompareInt());
12     //方法3:使用预定义的Adapter, 定义在 <functional> 中
13     sort(ar.begin(), ar.end(), greater<int>());
14     //方法4:正常排序,然后翻转过来
15     sort(ar.begin(), ar.end());
16     reverse(ar.begin(), ar.end());
17     //方法5:使用逆迭代器
18     sort(ar.rbegin(), ar.rend());
19 }

2、stable_sort

sort优点一大堆,一个缺点就是它不是一种稳定的排序。什么是排序的稳定性?就是如果出现两个元素相等时,要求排序之后他们之间保持原来的次序(比如我们先按学号排序,然后按成绩排序,这时就希望成绩相同的还是按照学号的次序排)。很可惜,快速排序算法就不是稳定的,要追求这个,只好用stable_sort了。

在各种排序算法中,合并排序是稳定的,但一般的合并排序需要额外的O(N)的存储空间,而这个条件不是一定能够满足的(可能是比较奢侈的)。所以在stable_sort内部,首先判断是否有足够的额外空间(如vecotr中的cap()-size()部分),有的话就使用普通合并函数,总的时间复杂性和快速排序一个数量级,都是O(N*logN)。如果没有额外空间,使用了一个merge_without_buffer的关键函数进行就地合并(如何实现是比较有技巧的,完全可以专门谈一谈),这个合并过程不需要额外的存储空间(递归的堆栈除外),但时间复杂度变成O(N*logN),这种情况下,总的stable_sort时间复杂度是O(N*logN*logN)。

总之,stable_sort稍微慢一点儿,但能够保证稳定,使用方法和sort一样。但很多时候可以不用这种方式和这个函数,比如上面的例子,完全可以在排序比较准则中写入成绩和学号两个条件就OK了。

class CStudent
{
public:
    CStudent();
    //注意这个比较函数中的const
    bool operator<(const CStudent& rhs) const
    {
        if (m_score != rhs.m_score)
            return (m_score <rhs.m_score);
        return m_name <rhs.m_name;
    }
protected:
    std::string m_name;
    int m_score;
};

void func4()
{
    vector<CStudent> arStu;
    sort(arStu.begin(), arStu.end());
}

3、heap_sort

堆排序也是一种快速的排序算法,复杂度也是O(N*logN)。STL中有一些和堆相关的函数,能够构造堆,如果在构造好的堆上每次取出来根节点放在尾部,所有元素循环一遍,最后的结果也就有序了。这就是sort_heap了。它的使用要求区间已经被构造成堆,如:

 1 void func5()
 2 {
 3     vector<int> ar;
 4     //生成数据
 5     generate_n(back_inserter(ar), 100, rand);
 6     //构造堆
 7     make_heap(ar.begin(), ar.end());
 8     //堆排序
 9     sort_heap(ar.begin(), ar.end());
10 }

4、list.sort

对于list容器,是不能直接使用sort的(包括stable_sort),从技术的角度来说,sort要求随机迭代器;从算法的角度来说,list这种链表结构本身就不适合用快速排序。因此,list容器内部实现了专门的sort算法,这个算法采用的是合并排序,应该是稳定的(不确定)。如:

1 list<int> li;
2     li.sort();
时间: 2024-10-29 01:10:00

STL 排序(转载)的相关文章

详细解说 STL 排序(Sort)(转)

作者Winter 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1.1 所有sort算法介绍 1.2 sort 中的比较函数 1.3 sort 的稳定性 1.4 全排序 1.5 局部排序 1.6 nth_element 指定元素排序 1.7 partition 和stable_partition 2 Sort 和容器 3 选择合适的排序函数 4 小结 5 参考文档 一切复杂的排序操作,都可以通过STL方便实现 ! 0 前言: STL,为

详细解说 STL 排序(Sort)

http://www.cppblog.com/mzty/archive/2005/12/15/1770.html 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1.1 所有sort算法介绍 1.2 sort 中的比较函数 1.3 sort 的稳定性 1.4 全排序 1.5 局部排序 1.6 nth_element 指定元素排序 1.7 partition 和stable_partition 2 Sort 和容器 3 选择合适的排序函数

深入理解Java内存模型(2) -- 重排序(转载)

转载出处:http://www.infoq.com/cn/articles/java-memory-model-2 数据依赖性 如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性.数据依赖分下列三种类型: 名称 代码示例 说明 写后读 a = 1;b = a; 写一个变量之后,再读这个位置. 写后写 a = 1;a = 2; 写一个变量之后,再写这个变量. 读后写 a = b;b = 1; 读一个变量之后,再写这个变量. 上面三种情况,只要重排序两个操作

STL排序算法sort

要使用STL中的算法,需要在程序头文件引入#include <algorithm> 1.对基本类型的数组从小到大排序: sort(数组名+n1,数组名+n2); n1和n2都是int类型的表达式,可以包含变量 如果n1=0,则 + n1可以不写  将数组中下标范围为[n1,n2)的元素从小到大排序.下标为n2的元素不在排序区间内 2.对元素类型为T的基本类型数组从大到小排序: sort(数组名+n1,数组名+n2,greater<T>()); 3.用自定义的排序规则,对任何类型T的

java按照map的value排序 转载http://blog.csdn.net/tsingheng/article/details/7909861

java的TreeMap可以排序,只可惜是按照key来排序的,或者重写其他Map的排序算法也都是按照key来排序的,下面贴出来一个按照value排序的算法: [java] view plaincopy public class SortMap { public static void main(String[] args) throws Exception { // TODO code application logic here Map<String, Integer> myMap = ne

AIM Tech Round 4 (Div. 2)(A,暴力,B,组合数,C,STL+排序)

A. Diversity time limit per test:1 second memory limit per test:256 megabytes input:standard input output:standard output Calculate the minimum number of characters you need to change in the string s, so that it contains at least k different letters,

c++STL排序算法注意事项

关于算法中的比较函数 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int compare(double a,double b){ 5 return a>b; 6 } 7 int main(){ 8 double a[10]={2.15,2.14,3.11,3.1010001,5,8,46,5,45,10}; 9 double b[10]={2.15,2.14,3.11,3.101000

(C++)STL排序函数sort和qsort的用法与区别

主要内容: 1.qsort的用法 2.sort的用法 3.qsort和sort的区别 qsort的用法: 原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)); 功 能: 使用快速排序例程进行排序 参 数: 1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针,用于确定排序的顺序 说 明:qsort函数是ANSI C标准中提供的,其

希尔排序 转载

希尔排序是对插入排序的一种改进算法,是一种分组插入排序,又称为缩小增量排序法. 希尔排序的时间复杂度与增量(即,步长gap)的选取有关.例如,当增量为1时,希尔排序退化成了直接插入排序,此时的时间复杂度为O(N²),而Hibbard增量(N/2)的希尔排序的时间复杂度为O(N3/2). (1).主要步骤: 对一个数组长度为N的数组,取一个小于N的整数gap(gap称为步长) 根据该步长将数组分为若干个子数组,所有距离为gap的倍数的记录放在同一个子数组 对每个子数组进行插入排序 然后缩减gap的