C++:std::sort() 函数详解

std::sort 详细解析

std::sort 是 C++ 标准库中的 通用排序函数,用于对 随机访问迭代器(Random Access Iterator) 指向的范围进行 就地排序(原地修改,不创建额外副本)。


1. std::sort 语法

(1)默认排序(升序,使用 < 运算符)

#include <algorithm>

void sort(RandomAccessIterator first, RandomAccessIterator last);
  • 参数
    • first:排序范围的起始迭代器(包含)。
    • last:排序范围的结束迭代器(不包含)。
  • 默认按照 < 进行升序排序

(2)自定义比较函数

void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
  • 参数
    • comp:比较函数(返回 true 表示前者应排在前面)。

示例:

std::sort(vec.begin(), vec.end(), std::greater<int>()); // 降序排序

2. std::sort 示例

(1)对 std::vector 进行升序排序

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

int main() {
    std::vector<int> vec = {5, 2, 8, 1, 3};
    std::sort(vec.begin(), vec.end());

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

输出:

1 2 3 5 8

(2)自定义排序(降序)

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

int main() {
    std::vector<int> vec = {5, 2, 8, 1, 3};
    std::sort(vec.begin(), vec.end(), std::greater<int>());

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

输出:

8 5 3 2 1

(3)对 std::pair 按照第一个元素排序

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

int main() {
    std::vector<std::pair<int, char>> vec = {{3, 'C'}, {1, 'A'}, {2, 'B'}};
    std::sort(vec.begin(), vec.end());

    for (const auto& p : vec) {
        std::cout << p.first << p.second << " ";
    }
    return 0;
}

输出:

1A 2B 3C
  • 默认按照 pairfirst 进行排序std::pair 具有默认 < 操作符)。

(4)自定义比较函数

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

bool customComparator(const std::pair<int, char>& a, const std::pair<int, char>& b) {
    return a.second < b.second; // 按字符升序排序
}

int main() {
    std::vector<std::pair<int, char>> vec = {{3, 'C'}, {1, 'A'}, {2, 'B'}};
    std::sort(vec.begin(), vec.end(), customComparator);

    for (const auto& p : vec) {
        std::cout << p.first << p.second << " ";
    }
    return 0;
}

输出:

1A 2B 3C

解释:

  • 使用 customComparatorsecond(字符)排序。

3. std::sort 的内部实现

C++ 标准库的 std::sort 通常基于 IntroSort(混合排序算法),它结合了:

  1. 快速排序(QuickSort) —— 当递归深度较小时,使用快速排序(O(n log n))。
  2. 堆排序(HeapSort) —— 当递归深度超过阈值(~2 * log(n))时,改用堆排序(O(n log n))。
  3. 插入排序(InsertionSort) —— 当数据量较小时(如 n ≤ 16),使用插入排序(O(n²))。

IntroSort 结合了三种排序的优点

  • 快速排序 通常最快,但最坏情况(已排序数据)可能变成 O(n²)。
  • 堆排序 保证最坏情况下 O(n log n)。
  • 插入排序 适用于小数组,减少递归开销。

(1)QuickSort(快速排序)

  • 选择 “三数中值”(Median of Three) 作为基准值(pivot)。
  • 使用 Hoare PartitionLomuto Partition 进行分区。
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pivot = partition(arr, low, high);
        quickSort(arr, low, pivot - 1);
        quickSort(arr, pivot + 1, high);
    }
}
  • 当递归深度过大时,切换到 HeapSort。

(2)HeapSort(堆排序)

  • 最大堆 保证最坏情况下 O(n log n)。
void heapSort(int arr[], int n) {
    std::make_heap(arr, arr + n);
    std::sort_heap(arr, arr + n);
}
  • 在 QuickSort 递归过深时,切换到 HeapSort。

(3)InsertionSort(插入排序)

  • 子数组长度 ≤ 16 时,使用插入排序。
void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}
  • 减少递归开销,提升小规模排序效率。

4. std::sort 时间复杂度

排序算法最优情况平均情况最坏情况
快速排序O(n log n)O(n log n)O(n²)
堆排序O(n log n)O(n log n)O(n log n)
插入排序O(n)O(n²)O(n²)
  • std::sort 保证 O(n log n) 的最坏情况时间复杂度(由于 IntroSort)。
  • qsort() 更快(因为 std::sort 可以内联,避免 qsort() 的函数指针调用开销)。

5. std::sort vs std::stable_sort

函数稳定性时间复杂度适用情况
std::sort❌ 不稳定O(n log n)一般情况,最快
std::stable_sort✅ 稳定O(n log² n)需要保留相同元素顺序
  • std::sort 不保证相等元素的相对顺序
  • std::stable_sort 使用归并排序,保证稳定性

总结

  1. std::sort 是 C++ 的标准排序函数,基于 IntroSort(快速排序 + 堆排序 + 插入排序)
  2. 时间复杂度 O(n log n),比 qsort() 更快,因为 支持内联
  3. 默认升序排序,可 使用自定义比较函数 进行 降序或其他排序方式
  4. 适用于随机访问迭代器(如 vector, array),但不能用于 list(用 list::sort)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值