#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;class minHeap{private:int *heap;       //存储数据和key值的数组,为了简单在这人只存储整数key值int capacity;    // 数组的的最大容量int size;        // 目前为止数组中有数据的项的数量int isLeaf(int pos){return (pos<size&&pos>=(size/2)-1);}int left(int pos){return pos*2+1;}int right(int pos){return pos*2+2;}int parent(int pos){return (pos-1)/2;}public://constructor : 通过形参maxSize 用new 给heap指针分配maxSize个内存minHeap(int maxSize){heap=new int[maxSize];capacity=maxSize; // 把容量初始化为maxSizesize=0;   // 刚开始包含数据(key值)为零}// destructor :   通过delete函数把自己分配的内存先清楚,再交给destructor 处理~minHeap(){  delete[] heap;} // clear      :  clear的目的是清楚内存中的数据而不是清楚内存,所以我们为了方便先删除内存再进行分配void clear(){delete [] heap; //   先删除内存size=0; // 数据数量初始化为零heap=new int[capacity];// capacity 是容量不动,并通过他再分配内存}//deleteFirst :  删除heap的第一个(根)元素  并返回其中内容int deleteFirst(){if(size==0)  // 如果heap为空 没有删除的项  退出函数并返回一个乱码(-9999999999)return -999999999; if(size==1){  //如果heap中只有一个元素(项) 那么size变零,退出函数并返回那个项的值size--;return heap[0];}int returnElement=heap[0]; //首先把删除项的key值赋给returnElement这个变量heap[0]=heap[--size];      //用最后一个元素进行覆盖第一个删除项的元素 并size要减少一个int pos=0; // 因为元素之间交换了数据 破坏了minHeap的基本属性,所以下面对minHeap重新整理 pos为除项的下标while(!isLeaf( pos)){  //当回复minHeap过程中,只要pos小标的项变成叶子是退出循环(或者不进入循环)int l=left(pos); int r=right(pos); // l 为pos项的左边孩子    r为pos项的右边孩子if(l<size&&heap[l]>heap[r])  //因为是minHeap所以pos项的元素要跟下面孩子的最小值比较所以 让l成为最小元素的坐标值l=r; //如果l的元素比r的元素小不会进入这个条件语句,反之会进入并将元素小的坐标r赋给l 使l成为最小元素坐标if(heap[pos]>heap[l]){ // 当前l是孩子中的最小元素坐标 ,所以pos(父)项的元素要跟l的元素比int temp=heap[pos]; //pos的元素如果大于l的元素不符合minHeap属性所以进行交换heap[pos]=heap[l];heap[l]=temp;}pos=l; //pos变成l继续循环直到pos是这个位置再没有孩子(叶子)}return returnElement; //返回当初的元素值}// 这个函数跟上面的类似,区别在于这里pos为形参可以是任何一个下表,上面只能是pos为0int deleteAny( int pos) {if(pos>=size)  //如果条件符合说明 给定的小标值大于size值 不符合处理 退出函数 返回乱码return -99999999;int returnNumber=heap[pos];heap[pos]=heap[--size];while(!isLeaf(pos)){int l=left(pos); int r=right(pos);if(l<size&&heap[l]>heap[r])l=r;if(heap[pos]>heap[l]){int temp=heap[pos];heap[pos]=heap[l];heap[l]=temp;}pos=l;}return returnNumber;}// insert a value(key) the heap void insert(int value){heap[size]=value; //  首先在size这个空位放入元素 int pos=size++;  // 讲插入元素的下标赋给pos ,并且size自增(因为加了一个元素size也要增多)while(pos!=0){   // 这层循环的目的是如果插入的元素小于上面那么一直循环到最顶端int p=parent(pos);if(heap[pos]>heap[p]) // 如果下面大于上面那么退出循环break;int temp=heap[pos]; //如果下面小于上面那么进行交换heap[pos]=heap[p]; //并且把p的值赋给pos,一直循环到最顶端heap[p]=temp;pos=p;}while(!isLeaf(pos)){  // 这个循环的意思是从pos的位置往下进行整理int l=left(pos); int r=right(pos);if(l<size&&heap[l]>heap[r])l=r;if(heap[pos]>heap[l]){int temp=heap[l];heap[l]=heap[pos];heap[pos]=temp;}pos=l;}}//decreaseKey 这个函数的目的是为了规定的位置的key值用value进行替换//  其实在这个实例中value也是key值,因为我们在heap中只存储key值 void decreaseKey(int pos,int value){if(pos>=size)  //不符合返回return ;heap[pos]=value;while(!isLeaf(pos)){int l=left(pos); int r=right(pos);if(l<size&&heap[l]>heap[r])l=r;if(heap[pos]>heap[l]){int temp=heap[pos];heap[pos]=heap[l];heap[l]=temp;}pos=l;}}
};
int main(int argc,char **argv){minHeap h(100);h.insert(10);h.insert(9);h.insert(11);h.insert(3);h.insert(12);h.insert(5);h.insert(100);h.decreaseKey(0,20);cout<<h.deleteFirst()<<endl;h.insert(1);h.deleteAny(0);cout<<h.deleteFirst()<<endl;return 0;
}//优化:#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
void swap(int *array,int a,int b){int temp=array[a];array[a]=array[b];array[b]=temp;
}class minHeap{private:int *heap;       //存储数据和key值的数组,为了简单在这人只存储整数key值int capacity;    // 数组的的最大容量int size;        // 目前为止数组中有数据的项的数量int isLeaf(int pos){return (pos<size&&pos>=(size/2)-1);}int left(int pos){return pos*2+1;}int right(int pos){return pos*2+2;}int parent(int pos){return (pos-1)/2;}void siftDown(int pos){while(!isLeaf(pos)){int l=left(pos); int r=right(pos);if(l<size&&heap[l]>heap[r])l=r;if(heap[pos]>heap[l])swap(heap,pos,l);pos=l;}}public://constructor :   通过形参maxSize 用new 给heap指针分配maxSize个内存minHeap(int maxSize){heap=new int[maxSize];capacity=maxSize; // 把容量初始化为maxSizesize=0;   // 刚开始包含数据(key值)为零}// destructor :   通过delete函数把自己分配的内存先清楚,再交给destructor 处理~minHeap(){  delete[] heap;} // clear      :  clear的目的是清楚内存中的数据而不是清楚内存,所以我们为了方便先删除内存再进行分配void clear(){delete [] heap; //   先删除内存size=0; // 数据数量初始化为零heap=new int[capacity];// capacity 是容量不动,并通过他再分配内存}//deleteFirst :  删除heap的第一个(根)元素  并返回其中内容int deleteFirst(){if(size==0)  // 如果heap为空 没有删除的项  退出函数并返回一个乱码(-9999999999)return -999999999; if(size==1){  //如果heap中只有一个元素(项) 那么size变零,退出函数并返回那个项的值size--;return heap[0];}int returnElement=heap[0]; //首先把删除项的key值赋给returnElement这个变量heap[0]=heap[--size];      //用最后一个元素进行覆盖第一个删除项的元素 并size要减少一个siftDown(0);return returnElement; //返回当初的元素值}// 这个函数跟上面的类似,区别在于这里pos为形参可以是任何一个下表,上面只能是pos为0int deleteAny( int pos) {if(pos>=size)  //如果条件符合说明 给定的小标值大于size值 不符合处理 退出函数 返回乱码return -99999999;int returnNumber=heap[pos];heap[pos]=heap[--size];siftDown(pos);return returnNumber;}// insert a value(key) the heap void insert(int value){heap[size]=value; //  首先在size这个空位放入元素 int pos=size++;  // 讲插入元素的下标赋给pos ,并且size自增(因为加了一个元素size也要增多)while(pos!=0){   // 这层循环的目的是如果插入的元素小于上面那么一直循环到最顶端int p=parent(pos);if(heap[pos]>heap[p]) // 如果下面大于上面那么退出循环break;swap(heap,pos,p);pos=p;}siftDown(pos);}//decreaseKey 这个函数的目的是为了规定的位置的key值用value进行替换//  其实在这个实例中value也是key值,因为我们在heap中只存储key值 void decreaseKey(int pos,int value){if(pos>=size)  //不符合返回return ;heap[pos]=value;siftDown(pos);}
};
int main(int argc,char **argv){minHeap h(100);h.insert(10);h.insert(9);h.insert(11);h.insert(3);h.insert(12);h.insert(5);h.insert(100);h.decreaseKey(0,20);cout<<h.deleteFirst()<<endl;h.insert(1);h.deleteAny(0);cout<<h.deleteFirst()<<endl;return 0;
}

C++ 实现堆(heap)相关推荐

  1. 一文搞懂栈(stack)、堆(heap)、单片机裸机内存管理malloc

    大家好,我是无际. 有一周没水文了,俗话说夜路走多了难免遇到鬼. 最近就被一个热心网友喷了. 说我的文章没啥营养,所以今天来一篇烧脑的. 哈哈,开个玩笑,不要脸就没人能把我绑架. 主要是最近研发第二代 ...

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

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

  3. 栈(stack)和堆(heap)

    栈(stack)和堆(heap), Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的.JVM运行时在内存中开辟一片内存区域,启动时在自己的内 ...

  4. (深入理解计算机系统) bss段,data段、text段、堆(heap)和栈(stack)(C/C++存储类型总结)(内存管理)

    文章目录 bss段 data段 text段 堆(heap) 栈(stack) 一个程序本质上都是由 bss段.data段.text段三个组成的. 存储类型总结 bss段 bss段(bss segmen ...

  5. codeforces 贪心+优先队列_算法与数据结构基础 - 堆(Heap)和优先级队列(Priority Queue)...

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值:

  6. Java里的堆(heap)栈(stack)和方法区(method)

    http://imiduo.iteye.com/blog/616310 Java里的堆(heap)栈(stack)和方法区(method)  <一> 基础数据类型直接在栈空间分配, 方法的 ...

  7. SQL Server 堆heap 非聚集索引 Nonclustered index 行号键查找RID loopup结合执行计划过程详解

    SQL Server 堆型数据与执行计划使用案例 索引的相关术语 1 堆(Heap)是一种没有指定排序的数据结构,通俗的理解堆就像是按照顺序排放的杂物.在数据库里也即是对应没有聚集索引. 2 聚集索引 ...

  8. java中堆栈(stack)和堆(heap)

    http://www.ej38.com/showinfo/java-172156.html 堆栈是一种先进后出的数据结构,只能在一端进行输入或输出数据的操作  Stack类在java.util包中 向 ...

  9. JVM之堆Heap参数调优入门

    JVM之堆Heap参数调优入门 目录: JVM体系结构概览 JVM之堆Heap参数调优入门 2.1 java7和 java8堆结构图 2.2 堆内存调优简介 1. JVM体系结构概览 2. JVM之堆 ...

  10. JVM之堆Heap体系概述

    JVM之堆Heap 目录: JVM体系结构概览 JVM之堆Heap解析 2.1 Heap 堆 2.2 新生区解析 2.3 永久带解析 1. JVM体系结构概览 2. JVM之堆Heap解析 2.1 H ...

最新文章

  1. python中time模块获取时间的使用
  2. oracle 迁移用户信息,Oracle备份一个用户并迁移
  3. 计算机基础知识二进步,大学计算机基础学习知识练习进步题(含规范标准答案).doc...
  4. Mysql的存储过程修改表的数据:项目上一个小练习
  5. 机器学习中的常用概率分布
  6. 《Linus Torvalds自传》摘录
  7. 比特币交易的脚本如何执行
  8. bpftrace 使用笔记
  9. mysql odbc 免安装_MySQL免安装版配置
  10. vue 键盘(上下左右)快捷键
  11. 中图杯获奖作品计算机组,我校代表队参加首届“中图杯”全国大学生先进制图技术与技能大赛取得优异成绩...
  12. switch-case案例*
  13. 使用IntelliJ Idea新建SpringBoot项目
  14. oracle灾备同步_浅析Oracle数据库的三种灾备技术
  15. Django的CBV和FBV
  16. 关于电脑插上耳机后扬声器与耳机同时播放声音。
  17. ubuntu安装ppa_如何在Ubuntu中从第三方PPA安装软件
  18. 华为手机最大屏是几英寸的_华为屏幕尺寸最大的手机,不是荣耀note10,而是这款发布仅三个月...
  19. ubuntu创建桌面图标
  20. Linux内核源码 ---- el2_setup源码解析

热门文章

  1. ubuntu编辑只读文件_在Ubuntu上U盘文件只读且无法删除怎么办?
  2. 使用Java操作office的案例
  3. 使用NX/UG小技巧
  4. flash与字符串:字符串与属性
  5. 四核处理器_攀升推出 MaxBook P1 笔记本:四核CPU+15.6英寸大屏,1899 元
  6. java毕业设计乐勤网书店源码+lw文档+mybatis+系统+mysql数据库+调试
  7. scrapy下载中间件(downloader middleware)和蜘蛛中间件(spider middleware)
  8. Python3.5 win10环境下导入kera/tensorflow报错的解决方法
  9. c语言读写nfc,NFC标识最新资讯
  10. 光子神经网络前沿—光子突触的STDP准则