C++ 标准库 排序算法

目录

        • 一 概述
        • 二 辅助函数
        • 三 std::sort
        • 四 std::stable_sort
        • 五 std::partial_sort
        • 六 std::patial_sort_copy
        • 七 std::nth_element
        • 八 std::make_heap
        • 九 std::push_heap
        • 十 std::pop_heap
        • 十一 std::sort_heap
        • 十二 github
        • 十三 参考

一 概述

  • C++ 标准库中提供了很多算法,定义于头文件 < algorithm >。本文主要探究以下用于 区间元素排序 的算法:
    • std::sort 元素排序
    • std::stable_sort 稳定排序
    • partial_sort 部分排序
    • partial_sort_copy 对范围内的元素进行复制并部分排序
    • std::nth_element 给定的范围部分排序,确保其按给定元素划分
    • std::make_heap 从一个元素范围创建出一个最大堆
    • std::push_heap 将一个元素加入到一个最大堆
    • std::sort_heap 将一个最大堆变成一个按升序排序的元素范围

二 辅助函数

  • 本文中Demo用到的辅助函数请参考此前文章 C++ 算法 查找元素。

三 std::sort

  • 定义
template< class RandomIt >
void sort( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void sort( RandomIt first, RandomIt last );(1)(C++20)
template< class ExecutionPolicy, class RandomIt >
void sort( ExecutionPolicy&& policy, RandomIt first, RandomIt last );(2)(C++17)
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );(3)(C++20)
template< class RandomIt, class Compare >
constexpr void sort( RandomIt first, RandomIt last, Compare comp );(3)(C++20)
template< class ExecutionPolicy, class RandomIt, class Compare >
void sort( ExecutionPolicy&& policy, RandomIt first, RandomIt last, Compare comp );(4)(C++17)
  • ExecutionPolicy 请参考此前文章 std::find std::execution。
  • Demo
if (1) {
  // std::sort 排序
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  print("before sort vc: ", vc);
  std::sort(vc.begin(), vc.end());
  print(" after sort vc: ", vc);
}
if (1) {
  // std::sort 排序
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  print("before sort vc: ", vc);
  std::sort(vc.begin(), vc.end(), greater<int>());
  print(" after sort vc: ", vc);
}
  • 结果
before sort vc: 1 7 3 5 2 4 6
 after sort vc: 1 2 3 4 5 6 7
before sort vc: 1 7 3 5 2 4 6
 after sort vc: 7 6 5 4 3 2 1

四 std::stable_sort

  • 定义
template< class RandomIt >
void stable_sort( RandomIt first, RandomIt last );(1)	
template< class ExecutionPolicy, class RandomIt >
void stable_sort( ExecutionPolicy&& policy, RandomIt first, RandomIt last );(2)(C++17)
template< class RandomIt, class Compare >
void stable_sort( RandomIt first, RandomIt last, Compare comp );(3)	
template< class ExecutionPolicy, class RandomIt, class Compare >
void stable_sort( ExecutionPolicy&& policy, RandomIt first,
                  RandomIt last, Compare comp );(4)(C++17)
  • Demo
if (1) {
  // std::stable_sort 稳定排序
  vector<pair<int, string>> mp{{1, "a"}, {3, "b"}, {2, "c"}, {1, "d"}};
  cout << "before stable_sort mp:" << endl;
  for (auto& item : mp) {
    cout << "   first: " << item.first << " second: " << item.second << endl;
  }
  std::stable_sort( mp.begin(), mp.end(),
      [](const pair<int, string>& f, const pair<int, string>& s) {
        return f.first < s.first;
      });
  cout << "after stable_sort mp:" << endl;
  for (auto& item : mp) {
    cout << "   first: " << item.first << " second: " << item.second << endl;
  }
}
  • 结果
before stable_sort mp:
   first: 1 second: a
   first: 3 second: b
   first: 2 second: c
   first: 1 second: d
after stable_sort mp:
   first: 1 second: a
   first: 1 second: d
   first: 2 second: c
   first: 3 second: b

五 std::partial_sort

  • 定义
template< class RandomIt >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void partial_sort( RandomIt first, RandomIt middle, RandomIt last );(1)(C++20)
template< class ExecutionPolicy, class RandomIt >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last );(2)(C++17)	
template< class RandomIt, class Compare >
void partial_sort( RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );(3)(C++20)
template< class RandomIt, class Compare >
constexpr void partial_sort( RandomIt first, RandomIt middle, RandomIt last,
                             Compare comp );(3)(C++20)
template< class ExecutionPolicy, class RandomIt, class Compare >
void partial_sort( ExecutionPolicy&& policy,
                   RandomIt first, RandomIt middle, RandomIt last,
                   Compare comp );(4)(C++17)
  • Demo
if (1) {
  // std::partial_sort 部分排序
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  print("before partial_sort vc: ", vc);
  std::partial_sort(vc.begin(), vc.begin() + 4, vc.end());
  print(" after partial_sort vc: ", vc);
}
  • 结果
before partial_sort vc: 1 7 3 5 2 4 6
 after partial_sort vc: 1 2 3 4 7 5 6

六 std::patial_sort_copy

  • 定义
template< class InputIt, class RandomIt >
RandomIt partial_sort_copy( InputIt first, InputIt last,
                            RandomIt d_first, RandomIt d_last );(1)(C++20)
template< class InputIt, class RandomIt >
constexpr RandomIt partial_sort_copy( InputIt first, InputIt last,
                                      RandomIt d_first, RandomIt d_last );(C++20)
template< class ExecutionPolicy, class ForwardIt, class RandomIt >
RandomIt partial_sort_copy( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
                            RandomIt d_first, RandomIt d_last );(2)(C++17)
template< class InputIt, class RandomIt, class Compare >
RandomIt partial_sort_copy( InputIt first, InputIt last,
                            RandomIt d_first, RandomIt d_last,
                            Compare comp );(3)(C++20)
template< class InputIt, class RandomIt, class Compare >
constexpr RandomIt partial_sort_copy( InputIt first, InputIt last,
                                      RandomIt d_first, RandomIt d_last,
                                      Compare comp );(3)(C++20)
template< class ExecutionPolicy, class ForwardIt, class RandomIt, class Compare >
RandomIt partial_sort_copy( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
                            RandomIt d_first, RandomIt d_last,
                            Compare comp );(4)(C++17)
  • Demo
if (1) {
  // std::partial_sort_copy 对范围内的元素进行复制并部分排序
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  std::vector<int> vc1(3);
  print("before partial_sort_copy vc: ", vc);
  print("before partial_sort_copy vc: ", vc1);
  std::partial_sort_copy(vc.begin(), vc.end(), vc1.begin(), vc1.end());
  print(" after partial_sort_copy vc: ", vc);
  print(" after partial_sort_copy vc: ", vc1);
}
if (1) {
  // 注意copy范围
  // std::partial_sort_copy
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  std::vector<int> vc1(8);
  print("before partial_sort_copy vc: ", vc);
  print("before partial_sort_copy vc: ", vc1);
  std::partial_sort_copy(vc.begin(), vc.end(), vc1.begin(), vc1.end());
  print(" after partial_sort_copy vc: ", vc);
  print(" after partial_sort_copy vc: ", vc1);
}
  • 结果
before partial_sort vc: 1 7 3 5 2 4 6
 after partial_sort vc: 1 2 3 4 7 5 6
before partial_sort_copy vc: 1 7 3 5 2 4 6
before partial_sort_copy vc: 0 0 0
 after partial_sort_copy vc: 1 7 3 5 2 4 6
 after partial_sort_copy vc: 1 2 3
before partial_sort_copy vc: 1 7 3 5 2 4 6
before partial_sort_copy vc: 0 0 0 0 0 0 0 0
 after partial_sort_copy vc: 1 7 3 5 2 4 6
 after partial_sort_copy vc: 1 2 3 4 5 6 7 0
  • 说明
    • 复制范围是源区间和目的区间范围的较小值。

七 std::nth_element

  • 定义
template< class RandomIt >
void nth_element( RandomIt first, RandomIt nth, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void nth_element( RandomIt first, RandomIt nth, RandomIt last );(1)(C++20)
template< class ExecutionPolicy, class RandomIt >
void nth_element( ExecutionPolicy&& policy,
                  RandomIt first, RandomIt nth, RandomIt last );(2)	(C++17)
template< class RandomIt, class Compare >
void nth_element( RandomIt first, RandomIt nth, RandomIt last,
                  Compare comp );(3)(C++20)
template< class RandomIt, class Compare >
constexpr void nth_element( RandomIt first, RandomIt nth, RandomIt last,
                            Compare comp );(3)(C++20)
template< class ExecutionPolicy, class RandomIt, class Compare >
void nth_element( ExecutionPolicy&& policy,
                  RandomIt first, RandomIt nth, RandomIt last,
                  Compare comp );(4)(C++17)
  • Demo
if (1) {
  // std::nth_element 给定的范围部分排序,确保其按给定元素划分
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  print("before nth_element vc: ", vc);
  std::nth_element(vc.begin(),vc.begin() + 4, vc.end());
  print(" after nth_element vc: ", vc);
}
  • 结果
before nth_element vc: 1 7 3 5 2 4 6
 after nth_element vc: 1 2 3 4 5 6 7

八 std::make_heap

  • 定义
template< class RandomIt >
void make_heap( RandomIt first, RandomIt last );(1)(until C++20)
template< class RandomIt >
constexpr void make_heap( RandomIt first, RandomIt last );(1)(since C++20)
template< class RandomIt, class Compare >
void make_heap( RandomIt first, RandomIt last, Compare comp );(2)(until C++20)
template< class RandomIt, class Compare >
constexpr void make_heap( RandomIt first, RandomIt last, Compare comp );(2)(since C++20)
  • Demo
if (1) {
  // std::make_heap 从一个元素范围创建出一个最大堆
  std::vector<int> vc{1, 7, 3, 5, 2, 4, 6};
  print("before make_heap vc: ", vc);
  std::make_heap(vc.begin(), vc.end());
  print(" after make_heap vc: ", vc);
}
  • 结果
before make_heap vc: 1 7 3 5 2 4 6
 after make_heap vc: 7 5 6 1 2 4 3
  • 说明
    • 相关算法 std::is_heap(C++11)std::is_heap_until(C++11) 请参考此前文章C++11 算法 区间是否构成堆.

九 std::push_heap

  • 定义
template< class RandomIt >
void push_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void push_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt, class Compare >
void push_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
template< class RandomIt, class Compare >
constexpr void push_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
  • Demo
if (1) {
  // 接上八
  // std::push_heap 将一个元素加入到一个最大堆
  vc.emplace_back(8);
  std::push_heap(vc.begin(), vc.end());
  print(" after push_heap vc: ", vc);
}
  • 结果
after push_heap vc: 8 7 6 5 2 4 3 1

十 std::pop_heap

  • 定义
template< class RandomIt >
void pop_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void pop_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt, class Compare >
void pop_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
template< class RandomIt, class Compare >
constexpr void pop_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
  • Demo
if (1) {
  // 接上九
  // std::pop_heap 从最大堆中移除最大元素
  std::pop_heap(vc.begin(), vc.end());
  print(" after pop_heap vc: ", vc);
  int e = vc.back();
  vc.pop_back();
}
  • 结果
after pop_heap vc: 7 5 6 1 2 4 3 8
  • 说明
    • 其实 std::pop_heap 是将最大元素移到容器末尾。

十一 std::sort_heap

  • 定义
template< class RandomIt >
void sort_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt >
constexpr void sort_heap( RandomIt first, RandomIt last );(1)(C++20)
template< class RandomIt, class Compare >
void sort_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
template< class RandomIt, class Compare >
constexpr void sort_heap( RandomIt first, RandomIt last, Compare comp );(2)(C++20)
  • Demo
if (1) {
  // 接上十

  // std::sort_heap 将一个最大堆变成一个按升序排序的元素范围
  std::sort_heap(vc.begin(), vc.end());
  print(" after sort_heap vc: ", vc);
}
  • 结果
after sort_heap vc: 1 2 3 4 5 6 7

十二 github

  • 所有Demo 已上传github cplusplus
  • sorting_algorithm.cpp

十三 参考

  • 《C++ 标准库 第2版》
  • cppreference

你可能感兴趣的:(#,C++98/03,#,STL)