目录
- 一 概述
- 二 辅助函数
- 三 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::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::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 起)
if (1) {
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 起)
if (1) {
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 起)
if (1) {
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) {
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 起)
if (1) {
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)
if (1) {
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 起)
if (1) {
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 起)
if (1) {
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 起)
if (1) {
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