#pragma once
#include<iostream>
using namespace std;
#include<vector>

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=Greater<T>>
class Heap
{
public:
    Heap()
    {}

Heap(const T* a, size_t size)   //建堆
    {
        for (int i = 0; i < size; ++i)      //先将数据push进vector中
        {
            _a.push_back(a[i]);
        }

for (int j = (_a.size() - 2) / 2; j > 0; j--)  //从非叶子节点开始,向下调整
        {
            AdjustDown(j);
        }
    }

bool Isempty()   //判空
    {
        return _a.empty();
    }

T& top()    //取栈顶元素
    {
        if (!_a.empty())
        return _a[0];
    }

void Pop()   //在树中删除节点
    {
        if (_a.empty())
            return;

//交换第一个节点与最后一个节点的值,删除最后一个节点,然后向下调整
        swap(_a[0], _a[_a.size() - 1]);  
        _a.pop_back();
        if (!_a.empty())
            AdjustDown(0);
    }

void Push(const T& x)    //在树中插入节点
    {
        _a.push_back(x);
        if (!_a.empty())
            AdjustUp(_a.size() - 1);   //向上调整最后一个节点
    }
protected:
    void AdjustUp(int child)    //向上调整
    {    
        while (child > 0)
        {
            Compare com;
            int parent = (child - 1) / 2;
            if (com(_a[parent] , _a[child]))
            {
                swap(_a[parent], _a[child]);
                child = parent;
            }    
            else
            {
                break;
            }
        }
    }

void AdjustDown(int root)   //小堆,子节点大于父节点
    {
        int parent = root;
        int child = parent * 2 + 1;   //先为左节点
        while (child+1<_a.size())
        {
            Compare com;
            if (_a[child + 1]>_a[child])   //找出孩子节点中较大的那个数
                ++child;

if (child<_a.size()&&com(_a[parent] , _a[child]))   //比较父节点与孩子节点的大小然后作出相应的处理
            {
                swap(_a[parent], _a[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }
private:
    vector<T>  _a;
};

Heap堆的更多相关文章

  1. Heap堆的理解以及在IAR中如何设置堆的大小

    文章首发于浩瀚先森博客 堆栈的概念在脑海里已经存在有一段时间了,今天就测试来整理下Heap堆.栈以后再说. 堆区不像全局变量和局部变量总是有指定的内存大小,它是为了在程序运行时动态分配内存而设定的一块 ...

  2. java - Stack栈和Heap堆的区别

    首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:        堆存储 ...

  3. Heap(堆)和stack(栈)有的区别是什么。

    java的内存分为两类,一类是栈内存,一类是堆内存.栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个 ...

  4. JAVA Stack栈和Heap堆的区别(转)

          首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:      ...

  5. 逻辑运算符、三元运算符、for循环、stack(栈),heap(堆),方法区,静态域

    Lesson One 2018-04-17 19:58:39 逻辑运算符(用于逻辑运算,左右两边都是 true 或 false) 逻辑与-& 和 短路与-&& 区别: & ...

  6. Stack栈 Heap堆

    Stack(栈) 栈(stack) 又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈 ...

  7. linux heap堆分配

    heap堆分配在用户层面:malloc函数用于heap内存分配 void* malloc(size_t size); 进程的虚拟内存地址布局: 对用户来说,主要关注的空间是User Space.将Us ...

  8. 如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)

    背景 Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题. 有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手-) ...

  9. Delphi 堆栈 [ heap(堆) 和 stack(栈) ]

    程序需要的内存空间分为 heap(堆) 和 stack(栈); heap(堆) 是自由存储区, stack(栈) 是自动存储区; 使用 heap 需要手动申请.手动释放, 使用 stack 是自动申请 ...

  10. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

随机推荐

  1. 【HDU4405】Aeroplane_chess

    题意 飞行棋.有n+1格,开始时在0号格子,每一步都要扔一个dice(六个面,概率相同)哪一面朝上他就会向前走x+i步.当x+i大于等于N的时候,游戏结束.另外,地图上有m条航线.第i条航线可以直接从 ...

  2. HEIDSOFT

    HEIDSOFT ENTHUSIASTIC GITHUB USER heidsoft@sina.com GitHub Profile I'm a developer based in China.sh ...

  3. Selenium自动化测试WebDriver下载

    1. 所有版本chrome下载 是不是很难找到老版本的chrome?博主收集了几个下载chrome老版本的网站,其中哪个下载的是原版的就不得而知了. http://www.slimjet.com/ch ...

  4. Luogu 4238 【模板】多项式求逆

    疯狂补板中. 考虑倍增实现. 假设多项式只有一个常数项,直接对它逆元就可以了. 现在假如要求$G(x)$ $$F(x)G(x) \equiv 1 (\mod x^n)$$ 而我们已经求出了$H(x)$ ...

  5. 迁移ORACLE数据库文件到ASM

    迁移数据文件到ASM 数据库一致性情况下迁移:将数据库启动到mount状态,生成rman copy 语句,然后在rman中执行: SQL> startup mount SQL> selec ...

  6. [原创]Linux下使用Daemon实现服务器永久存活

    很多服务器端设计者,很少会考虑到服务器永久存活或热替换的问题,貌似真的很少 其中永久存活最大的理论支持就是,我们如何真正的保证一组服务器持续的存在,即便宕机? 其实没有人能保证自己写的代码那么完美无瑕 ...

  7. Linux Mint 17 搭建 JSP 环境

    一.配置Tomcat 服务器 1.下载 tomcat 2.解压后放到/usr/local目录下面 3.以root权限执行  chmod +x *.sh 4.启动 ./startup.sh#方式1 ./ ...

  8. javascript总结38: 神奇的this

    1 this的特性 this 是在函数中的 this 的指向 是在函数调用的时候决定的 this的指向. 谁调用这个函数,函数中的this就指向谁 function fn (){ console.lo ...

  9. HDU 6097 Mindis (计算几何)

    题意:给一个圆C和圆心O,P.Q是圆上或圆内到圆心距离相等的两个点,在圆上取一点D,求|PD| + |QD|的最小值 析:首先这个题是可以用三分过的,不过也太,.... 官方题解: 很不幸不总是中垂线 ...

  10. Class Loading Deadlocks

    By tomas.nilsson on Feb 28, 2010 Mattis keeps going strong, in this installment you get to learn eve ...