这次实现了堆,这个堆不是指系统堆栈的堆,是一种数据结构,见下图

堆的本质就是一个数组(上图中,红色的是值,黑色的是下标)简单的来说就是把一个数组看成是二叉树,就像上图

大堆和小堆分别是指根节点比孩子节点的值大或者是小,看了上图之后就可以发现,父亲节点和孩子节点之间下表的关系,parnet=(child-1)/2

利用这个关系就可以实现堆了,堆的基本方法有构造,析构,插入,删除,像大堆小堆这样特殊的堆肯定是要有调整函数来保持他们的特性的,所以我还写了向上调整和向下调整的函数

为了让大堆和小堆之间切换自如(就是方便维护),我写了两个仿函数,建立堆的对象时传个模版参数就好了

 #pragma once
#include<iostream>
#include<vector>
using namespace std; template<class T>
struct Less
{
bool operator()(const T& l,const T& r)
{
return l < r;
}
}; template<class T>
struct Greater
{
bool operator()(const T& l ,const T& r)
{
return l > r;
}
}; template<class T, class Compare = Less<T>>
class Heap
{
public:
Heap()
{ }
Heap(vector<T> a)
:array(a)
{
for (int i = (array.size() - ) / ; i >= ; --i)
{
AdjustDown(i);
}
}
Heap(T *a, size_t size)
{
for (int i = ; i < size; ++i)
{
array.push_back(a[i]);
}
for (int i = (array.size() - ) / ; i >= ; --i)
{
AdjustDown(i);
}
}
~Heap()
{ }
void Push(T x)
{
array.push_back(x);
AdjustUp(array.size()-);
}
void Pop()
{
swap(array.front(), array.back());
array.pop_back();
AdjustDown();
}
void AdjustDown(int root)
{
int child = root * + ;
while (child < array.size())
{
if (child + < array.size() && Compare()(array[child + ], array[child]))
{
child++;
}
if (Compare(array[root], array[child]))
{
swap(array[root], array[child]);
root = child;
child = root * + ;
}
else
{
break;
}
}
}
void AdjustUp(int child)
{
int parent = (child - ) / ;
while (child > )
{
if (Compare()(array[child], array[parent]))
{
swap(array[child], array[parent]);
child = parent;
parent = (child - ) / ;
}
else
{
break;
}
}
}
void Print()
{
for (int i = ; i < array.size(); ++i)
{
cout << array[i] << " ";
}
cout << endl;
}
int Size()
{
return array.size();
}
protected:
vector<T> array;
}; void TestHeap()
{
Heap<int> hp;
int a[] = { ,,,,,,,,, };
for (int i = ; i < ; ++i)
{
hp.Push(a[i]);
}
hp.Print();
}

当一个一个push插入的时候我们只需要把这个元素插入到数组的最后,然后顺着二叉树向上调整就可以了(只需要调整这一条线)

删除头元素(根节点)的时候,为了不破坏结构,我们选择先跟处于最后位置的元素交换,之后在末尾删除掉“根节点”,然后因为最大值(最小值)被换到了根节点,不符合小堆(大堆)的结构要求,只需要顺着这条路一直向下调整就可以了

我还写了一个构造函数接收的参数是一个vector,这是把整个vector调整成大堆(小堆),先找到最后一个元素的父亲节点,一直往前向下调整就可以了,因为这个父亲节点之前也肯定都是有孩子父亲节点

堆(Heap)的实现的更多相关文章

  1. JVM的堆(heap)、栈(stack)和方法区(method)

    JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...

  2. [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...

  3. 堆heap和栈Stack(百科)

    堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...

  4. (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)

    [color=red][/color]<一> 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈 ...

  5. Java中堆(heap)和栈(stack)的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...

  6. 优先队列Priority Queue和堆Heap

    对COMP20003中的Priority queue部分进行总结.图片来自于COMP20003 queue队列,顾名思义特点先进先出 priority queue优先队列,出来的顺序按照优先级prio ...

  7. python数据结构之堆(heap)

    本篇学习内容为堆的性质.python实现插入与删除操作.堆复杂度表.python内置方法生成堆. 区分堆(heap)与栈(stack):堆与二叉树有关,像一堆金字塔型泥沙:而栈像一个直立垃圾桶,一列下 ...

  8. 纸上谈兵: 堆 (heap)

    纸上谈兵: 堆 (heap)   作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 堆(heap)又被为优先队列(priority ...

  9. JVM 内存初学 堆(heap)、栈(stack)和方法区(method)

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...

  10. 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...

随机推荐

  1. 题解 P1339 【[USACO09OCT]热浪Heat Wave】

    题目链接 这道题纯属是一个裸的SPFA: 建议先把模板AC之后再做. 只需要做一些手脚,就是在加边的时候加一个双向边就好. 然后再第一次加点的时候 看不懂模板的出门左转度娘. 推荐下面一片讲解: 友链 ...

  2. POM很重要的3个关系

    POM有3个很重要的关系:依赖.继承.合成. 1.依赖关系 <dependencies></dependencies> 2.继承 <parent></pare ...

  3. SQL 单引号转义

    declare @userNum varchar(50),@waterNum varchar(50),@tableName varchar(20),@sql varchar(max) select @ ...

  4. bootstrap的其他

    情境文本颜色 <p class="text-muted">...</p> <p class="text-primary">. ...

  5. elementtaryos root密码更改

    在elementtaryos 终端中使用root 账户但不幸忘记密码怎么办?请进行如下操作...... 1.进入高级选项选中recovery mode 2.按e编辑,找到recovery nomode ...

  6. COCO2018 目标检测

    刚浏览了一下coco数据集官网,认真看了一下18年的目标检测任务,简单记录一下. coco2018目标检测挑战赛只进行实例分割的评比,虽然仍然可以输出bbox,但是不可以提交到比赛的服务器,原因是官方 ...

  7. n阶幻方

    前序 最近在学习一些经典的算法,搞得头昏脑涨,就想换换脑子.在家里的旧书堆里面乱翻,无意中将一本具有十多年历史的小学数学奥林匹克竞赛的书发掘了出来,能放到现在挺不容易的,就拿起来随便翻翻.看了看目录, ...

  8. python学习之路---day03

    一:数据类型转换 1:bool-->int 将bool转成 int型 True 是1 False是0 a=True c=int(a) print(c) b=False d=int(b) prin ...

  9. 洛谷 P3388 【模板】割点(割顶)

    题目链接 题解 今天复习了一下割点. 关于\(tarjan\)这里不多讲 \(dfn\)和\(low\)数组的定义想必大家都知道 仔细观察一下,可以发现 假设便利\(u->v\)这条边 如果 \ ...

  10. Asp.Net 远程连接Oracle数据库

    Asp.Net 远程连接Oracle数据库 首先从微软停止.Net FrameWork支持Oracle数据库的研发,转为第三方提供说起,微软是很有实力的公司,他在桌面领域令其他对手望其项背,产品战线也 ...