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

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

大堆和小堆分别是指根节点比孩子节点的值大或者是小,看了上图之后就可以发现,父亲节点和孩子节点之间下表的关系,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. mysql主从复制数据库

    mysql主从复制相信已经用得很多了,但是由于工作原因一直没怎么用过.趁着这段时间相对空闲,也就自己实现一遍.尽管互联网上已有大把类似的文章,但是自身实现的仍然值得记录. 环境: 主服务器:cento ...

  2. 运行Scrapy工程,报错ModuleNotFoundError: No module named 'win32api'解决方法

    1.运行爬虫scrapy crawl name,报错ScrpyModuleNotFoundError: No module named 'win32api' 2.解决方法: 在https://gith ...

  3. Python实现——一元线性回归(最小二乘法)

    2019/3/24 线性回归--最小二乘法公式法 暂时用python成功做出来了图像,但是其中涉及到的公式还是更多的来自于网络,尤其是最小二乘法公式中的两个系数的求解,不过目前看了下书高数也会马上提及 ...

  4. 请设计实现一个商城系统开发v2.0【代码优化】

    #!/usr/bin/env python 优化的部分:1.改用字典取键,来调用函数[原来是用if-else判断] [补充]:也可以用列表,按索引取,可以在列表最前面加一个“”任意元素,凑成一个.就和 ...

  5. Python和qqbot库开发简单的机器人

    from qqbot import QQBotSlot as qqbotslot, RunBot @qqbotslot def onQQMessage(bot, contact, member, co ...

  6. 【算法笔记】B1003 我要通过!

    1003 我要通过! (20 分) “答案正确”是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案 ...

  7. 【KMP】【矩阵加速】【递推】洛谷 P3193 [HNOI2008]GT考试 题解

        看出来矩阵加速也没看出来KMP…… 题目描述 阿申准备报名参加 GT 考试,准考证号为\(N\)位数\(X_1,X_2…X_n(0\le X_i\le9)\),他不希望准考证号上出现不吉利的数 ...

  8. 毕业设计 python opencv实现车牌识别 码云地址

    码云地址:https://gitee.com/yinghualuowu/Python_VLPR 删除了冗余代码,可以更加便于运行.其实是为了那些进不去github准备的~

  9. CodeChef - RIN 最小割应用 规划问题

    题意:给定\(n\)门课和\(m\)个学期,每门课在每个学期有不同的得分,需要选定一个学期去完成,但存在约束条件,共有\(k\)对课程需要\(a\)在\(b\)开始学前学会,求最大得分(原问题是求最高 ...

  10. C++ STL之Vector

    向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. vector 属于STL(Standard Template Library, 标准模板库)中的一种自定义的 ...