优先队列/堆
来源:互联网 发布:php获取html内容 编辑:程序博客网 时间:2024/06/05 15:22
template <typename T> class MaxQ {public:MaxQ(std::initializer_list<T> il) :_v(il) {}size_t size() { return _v.size(); }void showData() { for_each(_v.begin(), _v.end(), [](const T x) {std::cout << x << " "; }); std::cout << std::endl; }void insert(T value);T delMax();private:void swim(int k);void sink(int k);std::vector<T> _v;};//往队列中末尾插入元素,并调用swim将其放在合适的位置template <typename T>void MaxQ<T>::insert(T value){_v.push_back(value);swim(_v.size() - 1);}template <typename T>void MaxQ<T>::swim(int k){//k代表的是在数组中的位置//因为当k处于二叉堆的第2层,与第一层(即k=1)进行交换,所以这里的循环判断条件为 k > 1//当父结点_v[k/2]小于当前处理的结点_v[k]时,k结点往上移while (k > 1 && _v[k] > _v[k / 2]) {std::swap(_v[k], _v[k / 2]);k = k / 2;//跳至二叉堆的上一层}}//弹出二叉堆中最大的元素,由insert已知最大值存在_v[1]//将末尾元素提上来填补_v[1]的位置,接着将其下沉到合适的位置,因为堆在数组中的存储并不是有序的template <typename T>T MaxQ<T>::delMax(){assert(_v.size() >= 2);auto max = _v[1];std::swap(_v[1], _v[_v.size() - 1]);_v.pop_back();sink(1);return max;}template <typename T>void MaxQ<T>::sink(int k){while (2 * k <= _v.size()-1 ) {//当下沉至>2k位置,表示已经在堆的底层,循环终止int j = 2 * k;if (j < _v.size()-1 && _v[j] < _v[j + 1])//判断两个子结点的大小++j;if (_v[j] > _v[k])//判断父结点k和子结点j的大小std::swap(_v[j], _v[k]);elsebreak;//当父结点大于子结点,循环终止k = j;//向下沉}}
优先队列运用于在接近无限大N的输入中,找出最大(最小)的M个元素。
如果用数组来实现二叉堆的话,那么位置k的结点的父结点的位置为k/2,而它的两个子结点的位置分别为2k和2k+1
数组中A[0]不使用,示例代码中使用最大堆
优先队列能够保证插入元素和删除最大元素这两个操作复杂度为NlogM
阅读全文
0 0
- 堆和优先队列
- 堆和优先队列
- 优先队列--二叉堆
- 优先队列--堆
- 二叉堆/优先队列
- 优先队列(堆)
- 优先队列实现堆
- 堆 优先队列
- 优先队列(堆)
- 优先队列与堆
- 优先队列(堆)
- poj3253 堆/优先队列
- 优先队列 - 堆
- 优先队列(堆)
- 优先队列(堆)
- 堆,优先队列
- 堆和优先队列
- 优先队列(堆)
- 【转载】mysql索引总结----mysql 索引类型以及创建
- Picasso 用法及源码解析
- 你应该知道的9篇深度学习论文(CNNs 理解)
- 远程启动Redis,报错不能配置键空间通知(keyspace notifications)
- virtualbox win7 iis 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序
- 优先队列/堆
- 【如何校验邮件地址的有效性】第二篇 :原理一
- lua模块
- jsp
- 15个常用的javaScript正则表达式
- centos 6.8 安装 oracle 11g r2
- A Beginner's Guide To Understanding Convolutional Neural Networks
- SSH框架总结(框架分析+环境搭建+实例源码下载)
- 高性能服务器架构