堆(heap)

堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。
堆的性质:
1.堆中某个节点的值总是不大于或不小于其父节点的值。
2.堆总是一棵完全二叉树。

堆的分类

将根节点最大的堆叫做最大堆或大顶堆,根节点最小的堆叫做最小堆或小顶堆。常见的堆有二叉堆、斐波那契堆等。
堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4…n/2)
若将和此次序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。
每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:
大堆:

小堆:

堆的操作

build:建立一个空堆;
insert:向堆中插入一个新元素;
update:将新元素提升使其符合堆的性质;
get:获取当前堆顶元素的值;
delete:删除堆顶元素;
heapify:使删除堆顶元素的堆再次成为堆。
某些堆实现还支持其他的一些操作,如斐波那契堆支持检查一个堆中是否存在某个元素。

建堆效率

n个结点的堆,高度d =log2n。根为第0层,则第i层结点个数为2i,考虑一个元素在堆中向下移动的距离。大约一半的结点深度为d-1,不移动(叶)。四分之一的结点深度为d-2,而它们至多能向下移动一层。树中每向上一层,结点的数目为前一层的一半,而子树高度加一。
这种算法时间代价为Ο(n)由于堆有log n层深,插入结点、删除普通元素和删除最小元素的平均时间代价和时间复杂度都是
Ο(log n)。

关于堆的操作实现

在程序中,堆用于动态分配和释放程序所使用的对象。在以下情况中调用堆操作:
1.事先不知道程序所需对象的数量和大小。
2.对象太大,不适合使用堆栈分配器。
堆使用运行期间分配给代码和堆栈以外的部分内存。
传统上,操作系统和运行时库随附了堆实现。当进程开始时,操作系统创建称为进程堆的默认堆。如果没有使用其他堆,则使用进程堆分配块。语言运行时库也可在一个进程内创建单独的堆。(例如,C 运行时库创建自己的堆。)除这些专用堆外,应用程序或许多加载的动态链接库 (DLL) 之一也可以创建并使用单独的堆。Win32 提供了一组丰富的 API用于创建和使用专用堆。有关堆函数的优秀教程,请参阅 MSDN 平台 SDK 节点。
当应用程序或 DLL 创建专用堆时,这些堆驻留于进程空间中并且在进程范围内是可访问的。某一给定堆分配的任何数据应为同一堆所释放。(从一个堆分配并释放给另一个堆没有意义。)
在所有虚拟内存系统中,堆位于操作系统的虚拟内存管理器之上。语言运行时堆也驻留在虚拟内存之上。某些情况下,这些堆在操作系统堆的上层,但语言运行时堆通过分配大的块来执行自己的内存管理。绕开操作系统堆来使用虚拟内存函数可使堆更好地分配和使用块。
典型的堆实现由前端分配器和后端分配器组成。前端分配器维护固定大小块的自由列表。当堆收到分配调用后,它尝试从前端列表中查找自由块。如果此操作失败,则堆将被迫从后端(保留和提交虚拟内存)分配一个大块来满足请求。通常的实现具有每个块分配的开销,这花费了执行周期,也减少了可用存储区。
单个全局锁可防止多线程同时使用堆。此锁主要用于保护堆数据结构不受多线程的任意访问。当堆操作过于频繁时,此锁会对性能造成负面影响。

代码实现

#pragma once
template<class T>
class JBMinHeap
{
private://申请堆空间T *_minHeap = NULL;int _index,_maxSize;
public:JBMinHeap(int maxSize) {_maxSize = maxSize;_minHeap = new T[_maxSize];_index = -1;}JBMinHeap(JBMinHeap &h) {_index = h._index;_maxSize = h._maxSize;_minHeap = new T[_maxSize];for (int i = 0;i<_maxSize) {*_minHeap[i] = *h._minHeap[i];}}~JBMinHeap() {delete[]_minHeap;}//获取整个最小堆的头部指针T * getMinHeap() {return _minHeap;}//判断堆是不是空的bool isEmpty() {return _index == -1;}bool add(T x) {if (isFull()) {return false;}_index++;_minHeap[_index] = x;return true;}bool isFull() {return _index == _maxSize;}//堆进行向下调整void adjustDown(int index);//队进行向上调整void adjustUp(int index);//建堆运算void createMinHeap() {if (isEmpty()) {return;}for (int i = (_index-1)/2;i >-1;i--) {//直接从倒数第二层 逐层向下调整adjustDown(i);}}
};
template<class T>
void JBMinHeap<T>::adjustDown(int index) {if (isEmpty()) {return;}while (index<_index){T temp = _minHeap[index];//将当前索引的位置的值保存下来int oneC = 2 * index + 1;//获取到两个孩子的位置int twoC = 2 * index + 2;if (oneC == _index) {//若第一个孩子是整个堆最后一个位置 则直接执行交换操作并结束执行_minHeap[index] = _minHeap[oneC];_minHeap[oneC] = temp;return;}if (twoC >_index) {//如果第二个孩子的索引位置越界 结束执行return;}if (_minHeap[oneC] <= _minHeap[twoC]) {//正常情况的数据交互执行if (temp > _minHeap[oneC]) {_minHeap[index] = _minHeap[oneC];_minHeap[oneC] = temp;index = oneC;}else {//如果该处索引值已经是比两个孩子小 则结束循环index = _index;}}else {if (temp > _minHeap[twoC]) {_minHeap[index] = _minHeap[twoC];_minHeap[twoC] = temp;index = twoC;}else {index = _index;}}}
}
template<class T>
void JBMinHeap<T>::adjustUp(int index) {if (index > _index) {//大于堆的最大值直接returnreturn;}while (index>-1){T temp = _minHeap[index];int father = (index - 1) / 2;if (father >= 0) {//若果索引没有出界就执行想要的操作if (temp < _minHeap[father]) {_minHeap[index] = _minHeap[father];_minHeap[father] = temp;index=father;}else {//若果已经是比父亲大 则直接结束循环index = -1;}}else//出界就结束循环{index = -1;}}
}

【数据结构】什么是堆相关推荐

  1. 数据结构与算法---堆的基本操作

    堆的定义 堆可以看做是一种特殊的树,堆结构满足两个条件: 1.堆是一个完全二叉树. 2.堆的每一个节点的值都大于等于(或小于等于)其子节点的值. 大于等于子节点的值我们叫它:大顶堆 小于等于子节点的值 ...

  2. 0x17.基础数据结构 - 二叉堆

    目录 一.二叉堆 二.例题 0.AcWing 145. 超市 AcWing 146. 序列(POJ 2442) 三.HuffmanHuffmanHuffman树 1.AcWing 148. 合并果子 ...

  3. 数据结构与算法 | 堆

    二叉树的顺序结构 堆的概念及结构 堆的实现 二叉树的顺序结构 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费.而完全二叉树更适合使用顺序结构存储.现实中我们通常把堆(一种二叉树)使用 ...

  4. 数据结构 3优先队列(堆)

    堆(Heaps) 我们想要这样一种数据结构,他可以进行插入和删除,但删除的话,规定每次删除的都是所有元素中最小的那一个元素.这可以利用数组和链表实现,但最好的是利用二叉树实现.如果用二叉搜索树的话删除 ...

  5. 【数据结构】 实现 堆 结构 ---超细致解析

    目录 二叉树的性质: 二叉树的存储结构: 顺序存储: 链式存储: 堆的概念和性质: 堆的实现: 堆的初始化: 堆的插入: 向上调整函数: 堆的删除: 向下调整函数: 向上建堆: 向下建堆: TopK问 ...

  6. 【数据结构】【堆】堆的建立、插入和删除

    目录 一.堆的介绍 1. 用数组表示堆,如何区分父节点和子节点? 2. 堆的种类? 二.堆的插入.删除操作 1. 几个基本操作 2. 堆的插入 3. 堆的删除 三.堆的建立 1. 建堆的原理 2. 代 ...

  7. 数据结构与算法——堆的原理和实现

    目录 一.堆的原理 二.堆的实现 1.堆的定义 2.堆的初始化 3.向上调整算法 4.向上调整算法代码实现 5.堆的插入 6.向下调整算法 6.堆的删除 7.堆的大小 8.判断堆是否为空 总结 一.堆 ...

  8. [ 数据结构-C实现 ] 堆、堆排序的分析及实现

      目录 1.堆的概念结构及分类 1.2堆的分类 1.2.1 大堆 1.2.2 小堆 2. 堆的主要接口 3.堆的实现 3.1 堆的初始化 HeapInit 3.2 堆的销毁 HeapDestory ...

  9. 数据结构-二叉树和堆的实现

    二叉树 树的概念和结构 概念 结构 树的其他概念名词 树的孩子兄弟表示法 树的实际应用 二叉树的概念和结构 概念 特殊的二叉树 二叉树的性质 二叉树的存储结构 二叉树的顺序结构-堆 堆的实现 堆的向下 ...

  10. 【数据结构入门】堆(Heap)

    文章目录 一.堆的结构及实现(重要) 1.1 二叉树的顺序结构 1.2 堆的概念及结构 1.3 堆的实现 1.3.1 堆的向下调整算法 1.3.2 向下调整算法的时间复杂度 1.3.3 堆的创建(向下 ...

最新文章

  1. 在Ubuntu 14.04 64bit上安装redis 3.0.3
  2. java 并发统计_java并发编程|CountDownLatch计数器
  3. 评审关上了你CVPR的门?这还有Rebuttal的窗,7个小技巧送上
  4. Extjs显示时间兼容性问题——firefox正常显示,IE不正常出现NaN-NaN-NaN的解决方式...
  5. PDF:解决从PDF中复制文字时出现的空方框问题
  6. wxWidgets 示例演示 wxWrapSizer 的使用
  7. 图(关系网络)数据分析及阿里应用
  8. html5增强的页面元素
  9. 西游中算命先生袁守诚泄露了天机,为何却是泾河龙王被砍头?
  10. 多时隙编码aloha(MuSCA)与编码时隙aloha(CSA)协议分析
  11. linux 查看数据库和表
  12. Oracle客户端使用
  13. 函数----ModifyStyle
  14. 靶机渗透练习Vulnhub DriftingBlues-6
  15. 对标苹果开“旧机发布会”?罗永浩出任转转品牌推广大使
  16. 魔兽争霸3 ce基址 偏移
  17. 揭秘苹果内购的大漏洞和内购订阅的黑陷阱
  18. 7-38 数列求和-给定某数字A(1≤A≤9)以及非负整数N(0≤N≤100000),求数列之和S=A+AA+AAA+⋯+AA⋯A(N个A)。例如A=1, N=3时,S=1+11+111=123。
  19. 如今的iOS开发者优胜劣汰,如何提升让自己不被淘汰?
  20. 一道按顺序排列组合题的几种解法

热门文章

  1. 痞子衡嵌入式:语音处理工具Jays-PySPEECH诞生记(6)- 文语合成实现(pyttsx3, eSpeak1.48.04)...
  2. oa移动办公怎么修改服务器端口,移动办公oa怎么知道服务器地址
  3. 有限体积法(12)——SIMPLE算法
  4. 教育界「拼多多」卖课套路解析
  5. 关于《那些年啊,那些事——一个程序员的奋斗史》——24提到的鼻炎治疗方法
  6. 怎样打开xp默认共享?
  7. 零基础到入门React SSR
  8. pc端客户端爬虫_FIddler+Proxifer工具对windows PC客户端进行抓包
  9. android仿微信充值布局,仿微信充值金额输入框-自定义EditText
  10. 关于山外多功能调试助手的虚拟示波器的使用说明