堆(Heap)的实现
这次实现了堆,这个堆不是指系统堆栈的堆,是一种数据结构,见下图
堆的本质就是一个数组(上图中,红色的是值,黑色的是下标)简单的来说就是把一个数组看成是二叉树,就像上图
大堆和小堆分别是指根节点比孩子节点的值大或者是小,看了上图之后就可以发现,父亲节点和孩子节点之间下表的关系,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)的实现的更多相关文章
- JVM的堆(heap)、栈(stack)和方法区(method)
JVM主要由类加载器子系统.运行时数据区(内存空间).执行引擎以及与本地方法接口等组成.其中运行时数据区又由方法区Method Area.堆Heap.Java stack.PC寄存器.本地方法栈组成. ...
- [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...
- 堆heap和栈Stack(百科)
堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...
- (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)
[color=red][/color]<一> 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收. 引用数据类型,需要用new来创建,既在栈 ...
- Java中堆(heap)和栈(stack)的区别
简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...
- 优先队列Priority Queue和堆Heap
对COMP20003中的Priority queue部分进行总结.图片来自于COMP20003 queue队列,顾名思义特点先进先出 priority queue优先队列,出来的顺序按照优先级prio ...
- python数据结构之堆(heap)
本篇学习内容为堆的性质.python实现插入与删除操作.堆复杂度表.python内置方法生成堆. 区分堆(heap)与栈(stack):堆与二叉树有关,像一堆金字塔型泥沙:而栈像一个直立垃圾桶,一列下 ...
- 纸上谈兵: 堆 (heap)
纸上谈兵: 堆 (heap) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 堆(heap)又被为优先队列(priority ...
- JVM 内存初学 堆(heap)、栈(stack)和方法区(method)
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...
- 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...
随机推荐
- logback&slf4j学习笔记
1.Slf4j 1.1.Slf4j简介 SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.实际上,SLF ...
- sed的基本用法
了解sed的基本参数 sed匹配的方法: '//'p, 此符号与grep的引号类似,但sed是一定加此符号的,且还要加上-n的参数,匹配起来相当麻烦.sed匹配的方法: '//'pI 加上I的参数是指 ...
- UML类图和时序图符号
看懂UML类图和时序图 https://www.cnblogs.com/me115/p/4092632.html 内容目录: 从一个示例开始 类之间的关系 时序图 附录:<图说设计模式> ...
- Apache htaccess 设置....
NC: no case,就是说不区分大小写R:redirect,重定向F:forbidden,禁止访问L:last,表示已经是最后一条规则,.htaccess文件解析即将退出 比如原地址为 /beau ...
- mfix mpi并行死锁问题探究
目前还没找到具体原因,只能先记录一下.(问题原因找到了) 分别用ubuntu14.04和ubuntu16.04测试,用的是笔记本,笔记本为双核四线程,用2线程并行计算:发现ubuntu16.04会在0 ...
- 前端PostJosn,后端转化相应的类
/// <summary> /// JsonPost特性类 /// </summary> [AttributeUsage(AttributeTargets.Method, In ...
- Hadoop 使用基础
[摘录自] https://www.yiibai.com/hadoop/hadoop_hdfs_operations.html#article-start 一.HDFS 使用基础 格式化配置HDFS文 ...
- naginx安装入门
一.nginx是什么 nginx是一个开源的,支持高性能,高并发的www服务和代理服务软件.它是一个俄罗斯人lgor sysoev开发的,作者将源代码开源出来供全球使用. nginx比它大哥apach ...
- RESTful和SOAP的区别
参考:[接口开发]浅谈 SOAP Webserver 与 Restful Webserver 区别 目录 一.Web Service 二.SOAP 三.REST 四.RPC 客户端和服务器端的通讯方式 ...
- Macbook使用Gitlab配置SSH Key
git是分布式代码管理工具,远程代码管理是基于ssh的,代码上传大搜gitlab或者github代码仓储时,需要进行ssh配置. 把本地代码上传到服务器时需要加密处理,git中公钥(id_rsa.pu ...