前言
排序是计算机编程中经常用到的一个操作,而stl中的sort()函数无疑是最常用的排序函数之一。本文将详细介绍sort()函数的原理和使用方法。
sort()函数概述
sort()函数是C++ STL中提供的标准排序算法,使用该函数可以对数组、vector、string等容器进行快速排序。sort()函数的定义如下:
template
void sort(RandomIt first, RandomIt last);
template
void sort(RandomIt first, RandomIt last, Compare comp);
其中,第一个模板参数是被排序范围的迭代器类型,第二个模板参数是元素的比较函数(可选)。
sort()函数原理
sort()函数的底层采用快速排序算法,其时间复杂度为O(nlogn)。快速排序的基本思想是分治法,具体过程如下:
1. 从数组中选择一个基准元素,通常选择第一个或最后一个元素;
2. 将数组中小于基准元素的元素移到左边,大于基准元素的元素移到右边;
3. 对左右两个子数组重复以上步骤,直到数组完全有序。
sort()函数的实现过程中采用了优化的快速排序算法,包括三个主要步骤:
1. 阈值。当数据集的规模较小时,sort()函数采用插入排序算法提高效率;
2. 中间值。sort()函数采用了isort算法,选择中间值作为比较基准,降低了worst-case时间复杂度;
3. 三向切分。由于有重复元素的存在,sort()函数采用三向切分的方式将数据集划分为小于、等于和大于基准元素的三部分,在大量重复元素存在的情况下,可以进一步提高排序效率。
sort()函数使用方法
对数组进行排序
sort()函数对数组进行排序非常简单,只需要将数组的起始地址和终止地址作为sort()函数的参数即可,示例如下:
int arr[] = {5, 3, 2, 4, 1};
int n = sizeof(arr) / sizeof(int);
sort(arr, arr+n);
对vector进行排序
对vector进行排序同样非常简单,只需要将vector的开始和结束迭代器作为sort()函数的参数即可,示例如下:
vector vec = {5, 3, 2, 4, 1};
sort(vec.begin(), vec.end());
自定义比较函数
sort()函数使用自定义的比较函数也很容易,只需要将自定义比较函数作为sort()函数的第三个参数传入即可。自定义比较函数的返回值应该是一个bool类型,表示两个元素的大小关系。
例如,对一个学生的信息按照成绩从高到低进行排序,代码如下:
struct Student {
string name;
int score;
};
bool cmp(Student a, Student b) {
return a.score > b.score;
}
vector stus;
sort(stus.begin(), stus.end(), cmp);
降序排序
sort()函数默认是升序排序,如果需要进行降序排序,可以使用自定义比较函数,其中将a和b参数交换位置即可,示例如下:
bool cmp(int a, int b) {
return a > b;
}
sort(arr, arr+n, cmp);
sort(vec.begin(), vec.end(), cmp);
如何保留下标信息
在实际应用中,经常需要对数组或vector中的元素进行排序,同时需要获取排序后的元素所在的初始位置。为了解决该问题,可以使用pair将元素值和下标信息进行组合,并通过自定义比较函数对元素值进行比较。最终,只需要通过访问pair中的second元素获取下标信息即可。
例如,对一个数组中的元素进行排序,示例如下:
int arr[] = {5, 3, 2, 4, 1};
int n = sizeof(arr) / sizeof(int);
vector> vec;
for (int i = 0; i < n; i++) {
vec.push_back(make_pair(arr[i], i));
}
sort(vec.begin(), vec.end(), greater>());
// 输出排序结果以及下标信息
for (int i = 0; i < n; i++) {
int val = vec[i].first;
int idx = vec[i].second;
cout << "value: " << val << " index: " << idx << endl;
}
总结
sort()函数是C++ STL中的标准排序函数,底层采用了优化的快速排序算法,时间复杂度为O(nlogn)。sort()函数使用非常简单,对数组、vector等容器进行排序都非常方便。为了保留下标信息,可以使用pair将元素值和下标信息进行组合,通过自定义比较函数对元素值进行比较,最终通过访问pair中的second元素获取下标信息。