std::sort
函数是<algorithm>
头文件中的一个模板函数,用于对容器中的元素进行排序。通常,std::sort
函数需要三个参数:
- 指向要排序序列的起始位置的迭代器。
- 指向要排序序列的结束位置之后一个位置的迭代器。
- 一个可选的比较函数或可调用对象,用于确定排序顺序。
当你只传递两个参数给std::sort
时,你实际上是在使用前两个必需的参数,而省略了第三个可选的比较函数。在这种情况下,std::sort
会使用元素的默认比较方式,这通常适用于内置类型(如整数和浮点数),它们已经定义了小于(<
)操作符,这种可用于直接对数组的大小进行排序。只需要直接传递数组的头元素和首元素即可。
当传递三个参数时,这里举例字符串数组中用字符串的长度对数组进行排序。
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
// 自定义比较函数,根据字符串长度进行比较
bool compareByLength(const std::string& a, const std::string& b) {
return a.length() < b.length();
}
int main() {
// 创建一个字符串向量
std::vector<std::string> strArray = {"apple", "banana", "kiwi", "cherry", "date"};
// 使用std::sort和自定义比较函数对字符串向量进行排序
std::sort(strArray.begin(), strArray.end(), compareByLength);
// 输出排序后的字符串向量
for (const auto& str : strArray) {
std::cout << str << " (length: " << str.length() << ")" << std::endl;
}
return 0;
}
这里是在第三个参数的时候调用了一个自定义函数compareByLength,在自定函数中明确了比较方法。函数调用的时候选择返回一个bool,原因如下:
std::sort
算法期望其比较函数(或可调用对象)返回一个布尔值(bool
),这是因为std::sort
需要这个返回值来确定两个元素之间的顺序关系。具体来说,std::sort
会使用这个返回值来决定元素是否应该交换位置以达到排序的目的。
比较函数或可调用对象接受两个参数,通常被命名为a
和b
,并返回一个bool
值,这个值告诉std::sort
算法a
应该在b
之前、之后,还是它们相等。根据这个返回值,std::sort
会决定是否需要交换这两个元素的位置。
- 如果比较函数返回
true
,则通常意味着a
应该在b
之前。 - 如果比较函数返回
false
,则通常意味着a
应该在b
之后或它们相等(取决于排序是稳定排序还是不稳定排序)。
使用bool
作为返回类型是明确且符合直觉的,因为bool
只有两个可能的值:true
和false
,这正好对应了两种可能的顺序关系。其他可以隐式转换为bool
的类型(如整数或指针),虽然技术上可能可行,但它们的语义可能不够清晰,容易导致错误和混淆。
也可以不用调用这个函数,而是使用lambda表达式,如下:
#include <iostream>
#include <algorithm>
#include <string>
int main() {
// 创建一个字符串数组
std::string strArray[] = {"apple", "banana", "kiwi", "cherry", "date"};
const size_t arraySize = sizeof(strArray) / sizeof(strArray[0]);
// 使用std::sort和lambda表达式对字符串数组进行排序
std::sort(strArray, strArray + arraySize, [](const std::string& a, const std::string& b) {
return a.length() < b.length();
});
// 输出排序后的字符串数组
for (size_t i = 0; i < arraySize; ++i) {
std::cout << strArray[i] << " (length: " << strArray[i].length() << ")" << std::endl;
}
return 0;
}
Lambda表达式:
Lambda表达式(也称为lambda函数或匿名函数)是C++11引入的一个新特性,它允许你定义一个匿名的内联函数对象,并可以将其用作任何需要函数对象的地方。Lambda表达式特别适用于需要小函数但又不希望编写整个函数定义或类定义的场合。
Lambda表达式的基本语法如下:
[capture](parameters) -> return_type { body_of_lambda }
capture
:捕获子句,定义了lambda表达式可以从其包围作用域中捕获哪些变量以及如何捕获这些变量。捕获可以是按值(=
)或按引用(&
),或者可以显式地列出要捕获的变量。parameters
:lambda函数的参数列表,与常规函数的参数列表类似。return_type
:返回类型。如果lambda体只包含单个返回语句,且其返回类型可以被编译器推导出,则可以省略此部分。否则,需要显式指定返回类型。body_of_lambda
:lambda函数的主体,即实现的功能代码。- 对于Lambda还有其他用法,详情请见其他文章。
时间复杂度:
std::sort
函数通常基于快速排序、归并排序或它们的混合实现,其平均时间复杂度为O(n log n),其中n是要排序的元素数量。这意味着排序时间大致与元素数量的对数成正比。这是排序算法中相当高效的时间复杂度,特别是对于大型数据集。
在最坏的情况下,std::sort
的时间复杂度可能接近O(n^2),但这通常只会在特定输入数据(例如已经排序或逆序的数组)上发生。然而,由于std::sort
的实现通常会尽量避免这种情况,因此在实际应用中很少会遇到最坏情况的时间复杂度。