概述
以下内容摘自cppreference中文离线文档。
文章目录
- std::make_heap
- std::push_heap
- std::pop_heap
- 案例
std::make_heap
定义于头文件 < algorithm>
(1)
C++20 前
template< class RandomIt >
void make_heap( RandomIt first, RandomIt last );
C++20 起
template< class RandomIt >
constexpr void make_heap( RandomIt first, RandomIt last );
(2)
C++20 前
template< class RandomIt, class Compare >
void make_heap( RandomIt first, RandomIt last, Compare comp );
C++20 起
template< class RandomIt, class Compare >
constexpr void make_heap( RandomIt first, RandomIt last, Compare comp );
在范围 [first, last) 中构造最大堆。函数第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp 。
参数
first, last - 制作堆来源的元素范围 (左闭右开区间!!)
comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true。
比较函数的签名应等价于如下:
bool cmp(const Type1 &a, const Type2 &b);
虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1 与 Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 与 Type2 必须使得 RandomIt 类型的对象能在解引用后隐式转换到这两个类型。
类型要求
-
RandomIt 必须满足遗留随机访问迭代器 (LegacyRandomAccessIterator) 的要求。
-
解引用 RandomIt 结果的类型必须满足可移动赋值 (MoveAssignable) 和可移动构造 (MoveConstructible) 的要求。
返回值
(无)
复杂度
至多 3*std::distance(first, last) 次比较。
注意
- 最大堆的元素范围 [f,l) :左闭右开
- 可用 std::push_heap() 添加新元素
- 可用 std::pop_heap() 移除首元素
示例
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
int main()
{
std::cout << "Max heap:n";
std::vector<int> v { 3, 2, 4, 1, 5, 9 };
std::cout << "initially, v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
std::make_heap(v.begin(), v.end());
std::cout << "after make_heap, v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
std::pop_heap(v.begin(), v.end());
std::cout << "after pop_heap, v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
auto top = v.back();
v.pop_back();
std::cout << "former top element: " << top << 'n';
std::cout << "after removing the former top element, v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n' << 'n';
std::cout << "Min heap:n";
std::vector<int> v1 { 3, 2, 4, 1, 5, 9 };
std::cout << "initially, v1: ";
for (auto i : v1) std::cout << i << ' ';
std::cout << 'n';
std::make_heap(v1.begin(), v1.end(), std::greater<>{});
std::cout << "after make_heap, v1: ";
for (auto i : v1) std::cout << i << ' ';
std::cout << 'n';
std::pop_heap(v1.begin(), v1.end(), std::greater<>{});
std::cout << "after pop_heap, v1: ";
for (auto i : v1) std::cout << i << ' ';
std::cout << 'n';
auto top1 = v1.back();
v1.pop_back();
std::cout << "former top element: " << top1 << 'n';
std::cout << "after removing the former top element, v1: ";
for (auto i : v1) std::cout << i << ' ';
std::cout << 'n';
}
输出:
Max heap:
initially, v: 3 2 4 1 5 9
after make_heap, v: 9 5 4 1 2 3
after pop_heap, v: 5 3 4 1 2 9
former top element: 9
after removing the former top element, v: 5 3 4 1 2
Min heap:
initially, v1: 3 2 4 1 5 9
after make_heap, v1: 1 2 4 3 5 9
after pop_heap, v1: 2 3 4 9 5 1
former top element: 1
after removing the former top element, v1: 2 3 4 9 5
std::push_heap
定义于头文件
(1)
C++20 前
template< class RandomIt >
void push_heap( RandomIt first, RandomIt last );
C++20 起
template< class RandomIt >
constexpr void push_heap( RandomIt first, RandomIt last );
(2)
template< class RandomIt, class Compare >
void push_heap( RandomIt first, RandomIt last,
Compare comp ); (C++20 前)
template< class RandomIt, class Compare >
constexpr void push_heap( RandomIt first, RandomIt last,
Compare comp ); (C++20 起)
插入位于位置 last-1 的元素到范围 [first, last-1) 所定义的最大堆中。函数的第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp 。
参数
first, last - 定义要修改的堆的元素范围
comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true 。
比较函数的签名应等价于如下:
bool cmp(const Type1 &a, const Type2 &b);
虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1 与 Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 与 Type2 必须使得 RandomIt 类型的对象能在解引用后隐式转换到这两个类型。
类型要求
- RandomIt 必须满足遗留随机访问迭代器 (LegacyRandomAccessIterator) 的要求。
- 解引用 RandomIt 结果的类型必须满足可移动赋值 (MoveAssignable) 和可移动构造 (MoveConstructible) 的要求。
返回值
(无)
复杂度
至多 log(N) 次比较,其中 N=std::distance(first, last) 。
示例
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v { 3, 1, 4, 1, 5, 9 };
std::make_heap(v.begin(), v.end());
std::cout << "v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
v.push_back(6);
std::cout << "before push_heap: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
std::push_heap(v.begin(), v.end());
std::cout << "after push_heap: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
}
输出:
v: 9 5 4 1 1 3
before push_heap: 9 5 4 1 1 3 6
after push_heap: 9 5 6 1 1 3 4
std::pop_heap
定义于头文件
(1)
template< class RandomIt >
void pop_heap( RandomIt first, RandomIt last );
(C++20 前)
template< class RandomIt >
constexpr void pop_heap( RandomIt first, RandomIt last );
(C++20 起)
(2)
template< class RandomIt, class Compare >
void pop_heap( RandomIt first, RandomIt last, Compare comp );
(C++20 前)
template< class RandomIt, class Compare >
constexpr void pop_heap( RandomIt first, RandomIt last, Compare comp );
(C++20 起)
交换在位置 first 的值和在位置 last-1 的值,并令子范围 [first, last-1) 变为堆。这拥有从范围 [first, last) 所定义的堆移除首个元素的效果。
函数的首个版本使用 operator< 比较元素,这使堆成为最大堆。第二版本使用给定的比较函数 comp 。
参数
first, last - 定义要修改的合法非空堆的元素范围
comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true 。
比较函数的签名应等价于如下:
bool cmp(const Type1 &a, const Type2 &b);
虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1 与 Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 与 Type2 必须使得 RandomIt 类型的对象能在解引用后隐式转换到这两个类型。
类型要求
- RandomIt 必须满足值可交换 (ValueSwappable) 和 遗留随机访问迭代器 (LegacyRandomAccessIterator) 的要求。
- 解引用 RandomIt 结果的类型必须满足可移动赋值 (MoveAssignable) 和可移动构造 (MoveConstructible) 的要求。
返回值
(无)
复杂度
至多 2×log(N) 次比较,其中 N=std::distance(first, last).
示例
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v { 3, 1, 4, 1, 5, 9 };
std::make_heap(v.begin(), v.end());
std::cout << "v: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
std::pop_heap(v.begin(), v.end()); // 移动最大元素到结尾
std::cout << "after pop_heap: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
int largest = v.back();
v.pop_back(); // 实际移出最大元素
std::cout << "largest element: " << largest << 'n';
std::cout << "heap without largest: ";
for (auto i : v) std::cout << i << ' ';
std::cout << 'n';
}
输出:
v: 9 5 4 1 1 3
after pop_heap: 5 3 4 1 1 9
largest element: 9
heap without largest: 5 3 4 1 1
案例
剑指offer的“最小的k个数”。
最后
以上就是忧心大白为你收集整理的C++的make_heap、push_heap、pop_heap的全部内容,希望文章能够帮你解决C++的make_heap、push_heap、pop_heap所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复