[草稿]std::sort

本章描述C++泛型算法sort的设计和使用。

个人认为,排序相关的泛型算法是C++中相对比较复杂的部分。

sort的内部实现并不是固定的,在不同版本的C++中,采用的排序算法可能是不同的,但是最坏时间复杂度必须是O(n log n)。

GNU Standard C++ library采用了三步混合排序方式:首先使用内省排序(本身采用快速排序和堆排序的混合),然后使用插入排序。

参见:http://en.wikipedia.org/wiki/Sort_(C%2B%2B)

(关于内省排序,参见:http://zh.wikipedia.org/wiki/%E5%86%85%E7%9C%81%E6%8E%92%E5%BA%8F)

或许是因为实现方法不固定,C++官方网站也并没有提供相关的实现方法。



我们先来看看C++官方网站上对sort的描述

http://www.cplusplus.com/reference/algorithm/sort/

(注:以下内容是我对C++官方网站上内容的理解,不准确的地方请见谅)

  • sort函数的声明:

sort函数有两种形式,

一种是默认采用operator<进行比较的形式:

template <class RandomAccessIterator>
void sort (RandomAccessIterator first, RandomAccessIterator last);

一种是采用自定义比较方式的形式:

template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

所以,如果你想对自定义类型的一组数据将进行排序,那么你有两种选择:1. 重载operator<; 2.采用第二种形式。

  • sort函数的作用:

对[first,last)序列中的元素进行排序(如果采用上边的第一种方式,则按降序排列)。

非稳定排序,即 相等的两个元素,在排序之后并不能保证其原来的先后循序。(如果需要稳定排序,请采用stable_sort)。



其他内容(还不够详细):

  • sort函数的时间复杂度:

最差时间复杂度 O(n log n)

  • sort函数的排序方式:

非稳定排序(如果需要稳定排序,请采用stable_sort)。

不同版本的C++中,sort采用的排序算法可能是不同的。GNU采用内省排序和插入排序的混合方式。



以下是我写得一个简单的例子

#include <algorithm>

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

class Whatever
{
public:
    Whatever(int size, char name)
        : mSize(size), mName(name)
    {}
    int getSize() { return mSize; }
    char getName() { return mName; }
    bool operator< (const Whatever& what) const
    {
        return (this->mSize < what.mSize);
    }
private:
    int mSize;
    char mName;
};

void print(vector<int> vec)
{
    for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++)
    {
        cout << *iter << ‘ ‘;
    }
    cout << endl;
}

void print(vector<Whatever> vec)
{
    for (vector<Whatever>::iterator iter = vec.begin(); iter != vec.end(); iter++)
    {
        cout << iter->getSize() << iter->getName() << ‘ ‘;
    }
    cout << endl;
}

bool compare(int i, int j)
{
    return (i > j);
}

bool compareWhat(Whatever i, Whatever j)
{
    return (i < j);
}

int main(void)
{
    int vecVal[] = {12, 10, 13, 15, 20, 18, 11};
    vector<int> vec(vecVal, vecVal+7);
    sort(vec.begin(), vec.end());
    print(vec);
    sort(vec.begin(), vec.end(), compare);
    print(vec);

    vector<Whatever> vecWhat;
    for (int i = 0; i < 100; i++)
    {
        Whatever what(rand()%50, char(97+rand()%25));
        vecWhat.push_back(what);
    }
    print(vecWhat);
    sort(vecWhat.begin(), vecWhat.end(), compareWhat);
    print(vecWhat);

    return 0;
}
时间: 2024-08-02 02:25:09

[草稿]std::sort的相关文章

std::sort 学习:一种递归分治方法

// std::sort 学习:一种递归分治方法 今天看了看 stl 的 std::sort 的代码,众所周知,这个函数是在快速排序递归太深的时候使用堆排序防止过度退化,但是今天说的不是这个.我们只看快速排序的部分. 我们一般实现快速排序大概是这样的(本王随意写了个用下标当参数的排序函数,领会意思即可). void quick_sort(int first, int last) // 某个数组的 [first, last) {  if ((last - first) > 1) {  int mi

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in

std::sort要求strict weak ordering

strict weak ordering简单地说就是小于语义,非小于等于语义,也就是说对于相等的或者异常的元素比较应当返回false 后果很严重,在google搜一下violating strict weak ordering make std::sort crash能看到很多种后果, 经测试,当待排序元素大于16个时使用std::sort,若传入的callable违反strict weak ordering,则可能死循环也可能越界访问. 待排序元素小于等于16个不会有问题是因为std::sor

测试std::sort 和std::qsort 的性能, 修改编译器栈大小

根据effective STL中Item 46 提到, C程序员很难接受C++的STL中std::sort(定义于头文件<algorithm>)竟然比C语言的std::qsort(定义与头文件<cstdlib>中)快了670%. 最后Scot Meyer建议我们我们要使用C++的std::sort函数. 我们知道qsort 实现的排序算法是快排, 但是std::sort 实现的排序算法并不知道, 有人说这得看是哪一个STL版本了. std::sort的大部分实现的是quick so

[C/C++标准库]_[初级]_[使用std::sort排序各种类型数据]

std::sort 场景: 1. 在使用sort排序时,有时候需要对对象的某个值进行排序,比如对类对象的某个id的int类型值或者bool类型值,其实bool类型值排序研究了半天.. test_sort.cpp #include <stdlib.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <iostream&

非常无聊——STD::sort VS 基数排序

众所周知,Std::sort()是一个非常快速的排序算法,它基于快排,但又有所修改.一般来说用它就挺快的了,代码一行,时间复杂度O(nlogn)(难道不是大叫一声"老子要排序!!"就排好了么...).我们也知道,不基于比较的排序可以达到O(n),比如说基数排序.什么,它是O(n * log(10)( max(n) ) ) 的?NO!!我们可以用sqrt(max(n))来作为进制,这样就是(N*logMax(n))=O(2*n)的了..看起来很不错, 代码量嘛....呵呵 所谓基数排序,

将三维空间的点按照座标排序(兼谈为std::sort写compare function的注意事项)

最近碰到这样一个问题:我们从文件里读入了一组三维空间的点,其中有些点的X,Y,Z座标只存在微小的差别,远小于我们后续数据处理的精度,可以认为它们是重复的.所以我们要把这些重复的点去掉.因为数据量不大,这里不准备使用划分包围盒或者建立k-d tree这样的重型武器,我们简单的把点按照其三维坐标进行排序就好. 我们准备使用STL的std::sort来做这个排序.它要求提供一个符合如下签名的比较函数: bool cmp(const Type1 &a, const Type2 &b) 怎么样写这个

std::sort()

原文地址:http://blog.csdn.net/factor2000/article/details/3936195 1 #include "stdafx.h" 2 #include <vector> 3 #include <algorithm> 4 #include <functional> 5 #include <iostream> 6 7 using namespace std; 8 9 //Return whether fir

GDB实践:一场std::sort引发的coredump

以前只掌握gdb一些基础知识,还没有真正"实战"过.刚好最近同事一个进程coredump了,原因比较深,正好利用这个机会来分析下 // @ 运行:gdb [可执行程序] -c [coredump文件] gdb edu_info_recommend_svr -c core_edu_info_recomm // @ 查看堆栈信息:bt (backtrace) (gdb) bt 10 #0 0x00007fa0809b6144 in __strcmp_sse42 () from /lib64