《数据结构》C++代码 堆(优先队列)
堆,是优先队列最常用的一种实现方式。在优先队列中,每个元素都被赋予了一个优先级,而每次出队时都让优先级最高的元素出队。堆,则是一种存储优先队列的方法,特指以一棵树形式存储的优先队列。最常用的是二叉堆,但既然是专门介绍数据结构,就不妨说全一些,我们取4个典型的堆进行比较,见下表(此表及表下备注,来自于广东省中山市第一中学黄源河前辈的《左偏树的特点及其应用》,并做过言辞修改及内容补充):
|
项目 |
二叉堆 |
左偏树 |
二项堆 |
Fibonacci堆 |
|
构建 |
O(n) |
O(n) |
O(n) |
O(n) |
|
插入 |
O(logn) |
O(logn) |
O(logn) |
O(1) |
|
取最小点 |
O(1) |
O(1) |
O(logn) |
O(1) |
|
删除最小点 |
O(logn) |
O(logn) |
O(logn) |
O(logn) |
|
删除任意点 |
O(logn) |
O(logn) |
O(logn) |
O(logn) |
|
合并 |
O(n) |
O(logn) |
O(logn) |
O(1) |
|
空间需求 |
最小 |
较小 |
一般 |
较大 |
|
编程复杂度 |
最低 |
较低 |
较高 |
很高 |
在此说明几点:
0、二项堆又称Bernoulli堆,左偏树又称左堆;斜堆并未在表中列出,是由于其复杂度与左偏树相同,没必要单独列出。其代码更简单,但常数较大,且在特殊数据下可能退化成O(n)。它与左偏树的关系,就像Splay与AVL的关系,并无优劣之分,前者更简洁灵活而后者更快。另外,我并未谈及D堆,那是因为这类仅在接触外存才值得应用的堆,我并不想提及。大家在考试用不上,平时也用不上,故而在我看来暂时了解、理解就好,之后真正用到了再去深究不迟。
1、二项堆,其“取最小点”的复杂度是O(log n),可以改进为O(1)。方法是,随时记录最小节点,并只在插入、删除以及合并等操作进行的时候更新该记录。
2、二项堆,其“插入”操作的平均时间复杂度为O(1),表中给出的是最坏时间复杂度。
3、Fibonacci堆,其“删除最小点”和“删除任意点”两个操作的时间复杂度均为平摊时间复杂度。
可能大家并未了解全,那就请自行搜索吧,我在此仅仅给出实现代码。由于种类过多,我仅仅对每种堆给出一种最常见的实现方式(例如二叉堆仅仅给出数组实现法),大家视题目需要而融会贯通即可。另外,由于代码较长,为了方便大家比较,我仅仅给出类版,实际实现时,不写成类有时反而方便许多。
还有,我依旧假设每个元素的信息仅有一个int权值,这样可以让大家更关注代码的框架结构,而不至于在繁琐的代码中看得迷迷糊糊。真正使用时,如果元素信息增多,视情况修改即可。
代码:
// 本代码所实现的是最小堆
const int maxk = ;
const int maxn = ;
inline swap(int &x,int &y) { int t=x; x=y; y=t; } // 二叉堆
// 实现了init、in、out操作
class Two_Heap
{
int H[maxn+],L; // H[1~L]是堆中元素
void up(int j)
{
int i=j>>;
if(i== || H[i]<H[j]) return;
swap(H[i],H[j]); up(i);
}
void down(int i)
{
int j=i<<;
if(j<L && H[j+]<H[j]) ++j;
if(j>L || H[i]<H[j]) return;
swap(H[i],H[j]); down(j);
}
public:
Two_Heap():L() {}
void init(int A[],int N)
{
// 以一个数组A[1~N]去初始化堆,这是堆排中建堆的过程,复杂度O(N)
L=N;
for(int i=;i<=N;++i) H[i]=A[i];
for(int i=N>>;i>=;--i) down(i); // 可以证明,从N/2开始调整即可,后N/2个点必然是叶子结点
}
void in(int x) { A[++L]=x; up(L); }
int out() { swap(A[],A[L--]); down(); return A[L+]; }
int min() { return A[]; }
}; // 未完待续
《数据结构》C++代码 堆(优先队列)的更多相关文章
- 纯数据结构Java实现(6/11)(二叉堆&优先队列)
堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). ...
- 算法&数据结构系列 -- 堆(优先队列)
前言 话说新开的博客十分好用... 所以,我打算开一个坑,名曰[算法系列]. 什么意思--从名字泥应该就猜得出来... 废话不多说,进入正文~~ 正文 原理 首先,堆是一颗棵二叉树.. 其次,堆是一棵 ...
- 数据结构(栈&堆 )
在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈是个特殊的存储区,主要功能 ...
- POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆
考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...
- Java数据结构和算法 - 堆
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
- POJ 2442 - Sequence - [小顶堆][优先队列]
题目链接:http://poj.org/problem?id=2442 Time Limit: 6000MS Memory Limit: 65536K Description Given m sequ ...
- 【bzoj2151】种树(堆/优先队列+双向链表)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 这道题因为优先队列不怎么会用,而且手写堆的代码也不长,也想复习一下手写堆的写法…… ...
- 堆&&优先队列&&TreeMap
题目描述 5710. 积压订单中的订单总数 题解 题目不难,主要是要读懂题意,一步步模拟,代码较长,需要细心检查. 坑较多,比如我犯了很多傻逼问题:想都不想就拿1<<9+7当作100000 ...
- 数据结构作业——Sanji(优先队列)
山治的婚约 Description 我们知道,山治原来是地下有名的杀人家族文斯莫克家族的三子,目前山治的弟弟已经出现,叫做四治,大哥二哥就叫汪(One)治跟突(Two)治好了(跟本剧情无关) .山治知 ...
随机推荐
- JAX-WS @WebParam自定义参数名称无效
在使用myeclipse 自动对service方法类进行创建webservice服务时,默认创建参数命名都是arg0-9 这样就导致生成的xml配置文件命名不规范,需要对参数名称进行修改: myecl ...
- April 26 2017 Week 17 Wednesday
We read the world wrong and say that it deceives us. 我们把世界看错了,反而说它欺骗了我们. It is not a cakewalk to see ...
- 【CSS古话今说】-- 01.神奇的CSS-BFC在实战中的应用
文章首发于掘金 BFC(Block Formatting Context)是Web页面中盒模型布局的CSS渲染模式.它的定位体系属于常规文档流. 想要实现一个BFC布局需要满足以下条件之一: 1.fl ...
- 【转】DataURL在Web浏览器中的兼容性总结
IE8+,Firefox,Chrome,Opera,Safari 等现代浏览器普遍支持data URL IE8 data URL 最大长度限制为32k字节,超出无效.IE9+没有这个限制 IE只识别b ...
- 【转】普及一下ARM和X86的区别,鉴于ATOM已经入驻手机,AMD也会…
这里简单来谈一下,ARM和X86之间为什么不太具有可比性的问题.要搞清楚这个问题首先要明白什么是架构,之前也有很多人提到了架构不同,但架构是什么意思?它是一个比较抽象的概念,不太容易用几句话就解释清楚 ...
- linux awk 内置函数详细介绍(实例)
这节详细介绍awk内置函数,主要分以下3种类似:算数函数.字符串函数.其它一般函数.时间函数 一.算术函数: 以下算术函数执行与 C 语言中名称相同的子例程相同的操作: 函数名 说明 atan2( y ...
- 第41章 RS-485通讯实验—零死角玩转STM32-F429系列
第41章 RS-485通讯实验 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...
- ADO.NET 之断开连接层
定义: 使用ADO.NET断开连接层,就会使用System.Data命名空间的许多成员(主要是DataTable.DataTable.DataRow.DataColumn.DataView和DataR ...
- django中的forms组件(权限信息校验,增删改查)
1.用处 1.用户请求数据验证 2.自动生成错误信息 3.打包用户提交的正确信息 4.如果其中有一个错误了,其他的正确,则保留上次输入的内容 5.自动创建input标签并可以设置样式 6.基于form ...
- 初尝微信小程序2-基本框架
基本框架: .wxml :页面骨架 .wxss :页面样式 .js :页面逻辑 描述一些行为 .json :页面配置 创建一个小程序之后,app.js,app.json,app.wxss是必须的 ...