基于库函数的c++算法竞赛教程(一):排序算法(1)
在 C++ 标准库中,
sort函数是实现快速排序的最常用工具。
平均时间复杂度为 O(n log n)。
本文将系统梳理一维数组、二维数组的排序方法,以及如何通过自定义比较函数实现复杂排序逻辑。本文语法非特殊说名则默认采用下头文件与命名空间:
#include <bits/stdc++.h>
using namespace std;
一维数组排序
对于普通数组,sort 的使用非常直观,需要传入起始地址和结束地址的后一位。
int arr[6] = {5, 2, 8, 1, 9, 3}; |
关键要点:sort 的第二个参数是结束位置的下一个地址,即 arr + n(n 为元素个数)。
二维数组排序
二维数组的排序根据需求不同,主要有三种处理方式。
展平排序(视为一维)
将整个二维数组在内存中视为连续的一维空间进行排序,会破坏原有的行结构。
int arr[3][4] = { |
排序结果(所有元素按升序排列,原行列关系打乱):
1 1 2 3 |
每行单独排序(保留行结构)
遍历每一行,对每一行分别排序,保持行与行之间的相对顺序。
// 对每一行分别排序 |
排序结果(每行内部有序,行间顺序不变):
排序前 排序后 |
按列排序(自定义排序)
在实际应用中,经常需要按特定列排序(例如按学生成绩排序)。此时需要使用自定义比较函数或 Lambda 表达式。
场景示例
假设有以下学生数据(学号, 分数),目标是按分数升序排列:
| 学号 | 分数 |
|---|---|
| 1 | 20 |
| 3 | 10 |
| 2 | 30 |
| 4 | 5 |
实现代码
int arr[4][2] = { |
注意事项:
- 比较函数的参数
const int* a实际上代表二维数组的一行(即a[0]是学号,a[1]是分数) const修饰符可以省略,但建议保留以确保不修改原数据
多关键字排序(稳定排序扩展)
当主排序字段相同时,需要引入第二关键字。例如:先按分数升序,分数相同则按学号升序。
sort(arr, arr + 4, [](const int* a, const int* b) { |
逻辑解析:
- 首先比较分数
a[1]和b[1] - 如果分数不同,直接返回比较结果
- 如果分数相同(
else分支),比较学号a[0]和b[0]
总结
| 排序需求 | 方法 | 时间复杂度 | 是否改变结构 |
|---|---|---|---|
| 一维数组 | sort(arr, arr+n) |
O(n log n) | - |
| 二维展平 | sort(arr[0], arr[0]+总元素) |
O(n log n) | 完全打乱行结构 |
| 行内排序 | 循环 sort(arr[i], arr[i]+m) |
O(n × m log m) | 仅行内有序 |
| 按列排序 | 自定义比较函数/Lambda | O(n log n) | 整行移动 |
| 多关键字排序 | 自定义比较函数/Lambda | O(n log n) | 整行移动 |
基于库函数的c++算法竞赛教程(一):排序算法(1)
