C++中堆的应用:make_heap, pop_heap, push_heap, sort_heap, priority_queue

本文介绍了C++标准库中与堆操作相关的模板函数,包括make_heap、pop_heap、push_heap和sort_heap,并通过示例展示了如何使用这些函数来操作vector容器中的元素。此外,还介绍了priority_queue容器适配器及其使用方法。

C++中堆的应用:make_heap, pop_heap, push_heap, sort_heap, priority_queue

make_heap, pop_heap, push_heap, sort_heap都是标准算法库里的模板函数,用于将存储在vector/deque 中的元素进行堆操作,对不愿自己写数据结构堆的C++选手来说,这几个算法函数很有用,下面是这几个函数操作vector中元素的例子。详细解释可以参见: http://www.cplusplus.com/reference/algorithm/push_heap/

隐藏行号 复制代码 Demo
  1. #include<iostream>
    
  2. #include<algorithm>
    
  3. #include<vector>
    
  4.  
  5. using namespace std;
    
  6.  
  7. void print_ivec(vector<int>::iterator begin, vector<int>::iterator end)
    
  8. {
    
  9.     for(;begin != end; ++begin)
    
  10.         cout << *begin << '/t';
    
  11.     cout << endl;
    
  12. }
    
  13.  
  14. int main(int argc, char* argv[])
    
  15. {
    
  16.     int a[] = {1, 12, 15, 20, 30};
    
  17.     vector<int> ivec(a, a + sizeof(a) / sizeof(a[0]));
    
  18.     print_ivec(ivec.begin(), ivec.end());
    
  19.      
    
  20.     make_heap(ivec.begin(), ivec.end(), greater<int>());
    
  21.     print_ivec(ivec.begin(), ivec.end());
    
  22.  
  23.     pop_heap(ivec.begin(), ivec.end());
    
  24.     ivec.pop_back();
    
  25.     print_ivec(ivec.begin(), ivec.end());
    
  26.  
  27.     ivec.push_back(99);
    
  28.     push_heap(ivec.begin(), ivec.end());
    
  29.     print_ivec(ivec.begin(), ivec.end());
    
  30.  
  31.     sort_heap(ivec.begin(), ivec.end());
    
  32.     print_ivec(ivec.begin(), ivec.end());
    
  33.  
  34.     return 0;
    
  35. }
    
  36.  
  37.  

Container Adaptors(容器适配器)priority_queue提供了更方便的堆数据结构,操作像queue, stack 一样简单方便,详情参见:

http://www.cplusplus.com/reference/stl/priority_queue/

 

隐藏行号 复制代码 Demo
  1. #include<iostream>
    
  2. #include<algorithm>
    
  3. #include<queue>
    
  4. using namespace std;
    
  5.  
  6. int main(int argc, char* argv[])
    
  7. {
    
  8.     priority_queue<int, vector<int>, greater<int>() > pq;
    
  9.     pq.push(676);
    
  10.     pq.push(34);
    
  11.     pq.push(23);
    
  12.     
    
  13.     while(!pq.empty())
    
  14.     {
    
  15.         cout << pq.top() << endl;
    
  16.         pq.pop();
    
  17.     }
    
  18.     return 0;
    
  19. }
    
### 相同点 - **数据结构本质**:`heap`()和`priority_queue`(优先队列)本质上都基于这种数据结构是一种完全二叉树,`priority_queue`默认使用`vector`作为底层存储数据的容器,在`vector`上使用算法将元素构造成的结构,因此`priority_queue`就是,所有需要用到的位置,都可以考虑使用`priority_queue` [^2]。 - **元素有序性**:二者都能保证元素的有序性,使得优先级最高的元素总是位于可访问的位置。在中,根节点(最大的最大值或最小的最小值)可以快速访问;在`priority_queue`中,优先级最高的元素总是位于队列的前端,可以通过`top()`函数访问到 [^1]。 - **插入和删除操作的时间复杂度**:插入和删除操作的时间复杂度都是 $O(log n)$,其中 $n$ 是元素的数量。在中进行插入和删除操作时,需要维护的性质,通常需要进行上浮或下沉操作;`priority_queue`的插入(`push`)和删除(`pop`)操作也需要类似的调整过程。 ### 不同点 - **实现形式**:`heap`并不是C++标准库中的一个具体容器,而是一种数据结构和算法概念,通常通过标准库中的算法(如`make_heap`、`push_heap`、`pop_heap`等)在`vector`或其他容器上实现;而`priority_queue`是C++标准模板库(STL)中的一种适配器容器,有自己独立的类定义和接口 [^1][^2]。 - **使用方式**:使用`heap`时,需要手动调用一系列的算法来维护的性质,例如创建、插入元素、删除元素等;而`priority_queue`提供了更简洁的接口,只需要调用`push`、`pop`、`top`等成员函数即可完成元素的插入、删除和访问操作。 - **接口特性**:`heap`没有封装特定的接口,操作依赖于通用的算法,操作容器时相对灵活但也需要更多的手动管理;`priority_queue`提供了更高级的封装,隐藏了的实现细节,使用起来更加方便,同时也限制了一些直接操作的灵活性。 以下是使用`heap`和`priority_queue`的简单代码示例: ```cpp #include <iostream> #include <vector> #include <queue> #include <algorithm> int main() { // 使用heap std::vector<int> heapVector = {3, 1, 4, 1, 5, 9}; std::make_heap(heapVector.begin(), heapVector.end()); std::cout << "Heap top: " << heapVector.front() << std::endl; std::pop_heap(heapVector.begin(), heapVector.end()); heapVector.pop_back(); std::push_heap(heapVector.begin(), heapVector.end()); // 使用priority_queue std::priority_queue<int> pq; pq.push(3); pq.push(1); pq.push(4); std::cout << "Priority queue top: " << pq.top() << std::endl; pq.pop(); pq.push(5); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值