C++ 实战:STL List 容器自定义排序深度解析
在 C++ STL 中, 是一个双向循环链表。与 不同,由于 的内存空间是不连续的,它不能使用系统提供的标准算法std::sort,而是内置了一个成员函数 。std::liststd::vectorlistsort()
今天我们就通过一个“人员排序”的实例,来看看如何利用 实现复杂的自定义排序逻辑。
1. 为什么 list 需要自定义排序?
在处理基本数据类型(如 或 )时,直接调用 即可实现升序。但当我们处理自定义类(如 对象)时,编译器不知道应该按“年龄”排还是按“身高”排,这时就需要我们提供一个排序规则(回调函数)。intfloatL.sort()person
2. 核心代码实现
以下代码展示了如何创建一个 类,并按照“年龄升序为主,身高降序为辅”的双重规则进行排序。person
#include<iostream>
#include<list>
#include<string>
using namespace std;
// 1. 定义数据实体
class person {
public:
person(string name, int age, int height) {
this->name = name;
this->age = age;
this->height = height;
}
string name;
int age;
int height;
};
// 2. 核心:定义排序规则
bool compareperson(person &p1, person &p2) {
// 逻辑:如果年龄相同,则按身高降序排列
if (p1.age == p2.age) {
return p1.height > p2.height; // 降序:前面的比后面大
}
// 逻辑:如果年龄不同,按年龄升序排列
else {
return p1.age < p2.age; // 升序:前面的比后面小
}
}
// 打印函数
void printList(const list<person>& L) {
for (list<person>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << "姓名:" << it->name << " \t年龄:" << it->age << " \t身高:" << it->height << endl;
}
}
void test01() {
list<person> L1;
// 准备测试数据
L1.push_back(person("张三", 22, 175));
L1.push_back(person("李四", 29, 165));
L1.push_back(person("王五", 81, 195)); // 年龄相同案例 A
L1.push_back(person("赵六", 81, 145)); // 年龄相同案例 B
L1.push_back(person("钱七", 38, 185));
L1.push_back(person("孙八", 44, 180));
cout << "排序前:" << endl;
printList(L1);
// 3. 执行排序:将自定义规则函数名作为参数传入
L1.sort(compareperson);
cout << "----------------" << endl;
cout << "排序后(年龄升序,年龄相同时身高降序):" << endl;
printList(L1);
}
int main() {
test01();
return 0;
}
3. 技术要点拆解
A. 排序算法的选择
对于 容器,我们通常使用 。但对于 ,由于其不支持随机访问迭代器,必须使用成员函数:vectorsort(L.begin(), L.end())list
L1.sort(compareperson);
B. 排序规则函数compareperson
这个函数决定了两个元素的“前后关系”:
返回
true:代表 应该排在 前面。p1p2返回
false:代表 应该排在 后面。p1p2升序写法:
p1.val < p2.val降序写法:
p1.val > p2.val
C. 多级排序逻辑
在代码中,我们通过 实现了嵌套逻辑。这在实际开发中非常实用,比如在电商网站排序时,可以先按价格排,价格相同时再按评价排。if (p1.age == p2.age)
4. 总结
使用 容器排序时,记住以下三步走:list
定义规则:编写一个返回类型为 的对比函数。
bool调用成员:使用 。
list对象.sort(规则名)注意性能:链表排序虽然不需要频繁移动内存(只需改变指针指向),但在大数据量下,其效率仍低于基于数组的 排序。
vector
