C++的sort函数使用详解

升序排序

C++ 的 sort 函数是标准库 <algorithm> 中提供的一种排序算法,用于对容器中的元素进行排序。它可以对各种容器类型进行排序,例如数组、向量(vector)、列表(list)等。

sort 函数的原型如下:

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

该函数接受两个迭代器参数,firstlast,用于指定排序范围。排序范围是半开区间 [first, last),其中 first 指向排序范围的第一个元素,而 last 指向排序范围之后的位置(即超过排序范围的下一个位置)。

sort 函数使用的是快速排序(Quick Sort)算法,通常具有较好的性能。以下是 sort 函数的一些特点和用法说明:

  1. 排序范围内的元素类型必须支持小于操作符(<),或者你可以通过自定义比较函数来指定排序规则。

  2. 默认情况下,sort 函数按照升序对元素进行排序。如果需要降序排序,可以使用 greater 函数对象或自定义比较函数。

  3. sort 函数通过修改容器中的元素来实现排序,而不是创建一个新的排序后的容器。

  4. sort 函数的时间复杂度通常为 O(n log n),其中 n 是排序范围内的元素数量。这使得它成为大多数情况下的首选排序算法。

以下是一个使用 sort 函数对向量进行排序的示例:

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> nums = {5, 2, 8, 1, 9};

    std::sort(nums.begin(), nums.end());

    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:1 2 5 8 9

此示例演示了对向量 nums 进行升序排序。sort 函数接受迭代器 nums.begin()nums.end(),指定了排序范围为整个向量。排序后,输出排序后的向量元素。

需要注意的是,sort 函数可以用于排序各种容器类型,只要容器支持随机访问迭代器。对于不支持随机访问的容器,如列表(list),可以使用其成员函数 sort 进行排序。

降序排序

要使用 sort 函数进行降序排序,可以通过两种方法实现:

方法一:使用 greater 函数对象

greater 是一个函数对象,可以用于比较两个元素的大小,并返回一个布尔值表示是否第一个元素大于第二个元素。使用 greater 可以实现降序排序,只需将其作为第三个参数传递给 sort 函数。

以下是一个使用 greater 实现降序排序的示例:

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> nums = {5, 2, 8, 1, 9};

    std::sort(nums.begin(), nums.end(), std::greater<int>());

    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:9 8 5 2 1

在这个示例中,std::greater<int>() 是一个函数对象,用于比较两个整数的大小并返回布尔值。通过将其作为 sort 函数的第三个参数传递,实现了按降序排序。

sort 函数的第三个参数---comp 参数是一个二元谓词(binary predicate),它接受两个元素作为参数,并返回一个 bool 值来指示它们的相对顺序。如果返回 true,则表示第一个元素在排序中应该排在第二个元素之前;如果返回 false,则表示第一个元素在排序中应该排在第二个元素之后

方法二:使用自定义比较函数

如果不想使用 greater 函数对象,还可以定义一个自定义的比较函数,根据需要来比较两个元素的大小,并返回一个布尔值。自定义比较函数需要接受两个参数,分别是待比较的两个元素,并返回比较结果。

以下是使用自定义比较函数实现降序排序的示例:

#include <algorithm>
#include <vector>
#include <iostream>

bool compare(int a, int b) {
    return a > b;
}

int main() {
    std::vector<int> nums = {5, 2, 8, 1, 9};

    std::sort(nums.begin(), nums.end(), compare);

    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果与前面的示例相同:9 8 5 2 1

在这个示例中,compare 函数是自定义的比较函数,用于比较两个整数的大小并返回布尔值。通过将其作为 sort 函数的第三个参数传递,实现了按降序排序。

无论是使用 greater 函数对象还是自定义比较函数,都可以实现对容器进行降序排序。选择其中一种方法来根据自己的需求进行排序即可。

迭代器所指元素为vector<int>型怎么比较

//vector<vector<int>>& intervals;
sort(intervals.begin(),intervals.end());

以上代码涉及到了对二维向量 intervals 进行排序操作。intervals向量的每一个元素是vector<int>类型,那么如何对vector<int>类型之间进行大小比较?

  • sort() 函数对 vector 元素的比较是通过 vector 对象元素类型的 operator< 运算符来实现的。
  • 对于 vector<int> 元素,它们的比较是按照vector<int>中元素的大小、从前往后进行的,因为 int 类型已经定义了 < 运算符用于比较。
  • 这还适用于支持 < 操作符的元素类型,如 intfloatstring 等。

例如,考虑以下二维向量示例 intervals

intervals = {{2, 5}, {1, 4}, {3, 6}, {1, 3}, {2, 1}};

intervals 进行排序后,结果将是:

intervals = {{1, 3}, {1, 4}, {2, 1}, {2, 5}, {3, 6}};

自定义的类类型如何比较

当你使用自定义的类类型,在使用 sort() 函数对对象进行排序时,你可以通过重载类的 operator< 运算符来定义对象之间的比较逻辑。

要自定义 operator< 运算符,你可以在类的定义中重载该运算符,并指定如何比较对象的大小。下面是一个示例,展示了如何自定义 operator< 运算符来对自定义类 MyClass 的对象进行排序:

class MyClass {
public:
    // 成员变量和其他成员函数的定义

    // 自定义 operator< 运算符
    bool operator<(const MyClass& other) const {
        // 比较逻辑,根据你的需求进行修改
        // 返回 true 表示当前对象小于参数对象,否则返回 false
        // 可以使用对象的某个属性或多个属性进行比较
        // 例如,比较对象的某个整数成员变量:
        return intValue < other.intValue;
    }

private:
    int intValue;
    // 其他成员变量和成员函数的定义
};

在上述示例中,我们重载了 MyClass 类的 operator< 运算符,通过比较对象的 intValue 成员变量来确定对象的大小关系。你可以根据自己的需要自定义比较逻辑,并根据类的具体属性进行比较。

然后,你可以使用 sort() 函数对包含 MyClass 对象的容器进行排序。例如:

std::vector<MyClass> myObjects;
// 添加 MyClass 对象到 myObjects 容器

// 对 myObjects 中的对象进行排序
std::sort(myObjects.begin(), myObjects.end());

在此示例中,sort() 函数将使用 MyClass 类型的对象的 operator< 运算符来比较并对容器中的对象进行排序。

注意区别
如何重载operator< 运算符---定义了对象之间如何比较

    // 重载 operator< 运算符
    bool operator<(const MyClass& other) const {
        // 比较逻辑,根据你的需求进行修改
        // 返回 true 表示当前对象小于参数对象,否则返回 false
        // 可以使用对象的某个属性或多个属性进行比较
        // 例如,比较对象的某个整数成员变量:
        return intValue < other.intValue;
    }

如何定义转换运算符operator---定义了如何将对象转换为其他类型值

operator T() const {
    // 转换逻辑
}
//例如
operator bool() const { return frame_ref != nullptr; }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 本节我们将继续介绍 STL 中的 list 容器使用。 list 容器排序及合并元素 sort() 函数定义在头文...
    思想永不平凡阅读 260评论 0 3
  • 本节我们将介绍 STL 中的 priority_queue 容器,堆的使用。 注:本节内容主要参考了C 语言中文网...
    思想永不平凡阅读 2,299评论 0 3
  • 想到之前面试官问我,sort用了什么排序方法,我还憨憨的想...不就是快排吗...今天才看到这篇文章。sort 包...
    吃掉夏天的怪物阅读 176评论 0 0
  • 原文地址: https://www.cnblogs.com/CnZyy/p/3317999.html 一、STL简...
    Caiaolun阅读 1,065评论 0 5
  • 仿函数 仿函数又称为函数对象,是一种能够行使函数功能的类,该类重载了operator()运算符,调用仿函数的时候实...
    克罗地亚催眠曲阅读 4,100评论 2 3