java实现堆结构
一、前言
之前用java实现堆结构,一直用的优先队列,但是在实际的面试中,可能会要求用数组实现,所以还是用java老老实实的实现一遍堆结构吧。
二、概念
堆,有两种形式,一种是大根堆,另一种是小根堆。堆,一般是二叉树,这个概念当然也可以扩展到k叉树。大根堆指的是根节点的值要大于左子树和右子树所有节点值,堆的子树也是堆。小根堆的概念同理可知。
三、实现过程
堆的形式是一棵树,但是我们可以用数组来实现它,父节点和孩子节点的父子关系通过数组下标来确定。
它的左右孩子节点和父节点的位置,如上图所示。
在接下来的实现过程,我们使用第二种表示方式,也就是说节点的编号是从0开始。
(1)首先我们需要定义一个节点的左右孩子的位置和根节点的位置。
- // find the index of left children
- public static int left(int i){
- return (i+1)*2 -1;
- }
- // find the index of right children
- public static int right(int i){
- return (i+1)*2;
- }
- // find the index of parent
- public static int parent(int i){
- return (i-1)/2;
- }
(2)其次我们需要保持堆的结构。所谓保持堆结构,指的是:让它的根节点始终比它的左右子树大(大顶堆)或者小(小顶堆)。具体做法就是在根节点和左右子树的根节点的值进行对比,如果根节点就是最大的话,就结束;否则就将根节点和最大值的位置互换,然后递归的变更最大值。
- //keep the max heap structure
- public static void heapkeep(int[] a, int i, int heaplength){
- int l = left(i);
- int r = right(i);
- int largest = i;
- if(l<heaplength&&a[i]<a[l]){
- largest = l;
- }
- if(r<heaplength&&a[largest]<a[r]){
- largest = r;
- }
- if(largest!=i){
- int temp = a[largest];
- a[largest] = a[i];
- a[i] = temp;
- heapkeep(a, largest, heaplength);
- }
- }
(3)构建堆。构建堆的方法很简单,就是自底向上的构建堆。
- // create the heap
- public static int heapcreate(int[] a, int length){
- if(a.length<length){
- return -1;
- }else{
- int pr = parent(length-1);
- for(int i = pr;i>=0;i--){
- heapkeep(a, i, length);
- }
- return 0;
- }
- }
上述实现过程,实现的大顶堆,如果想要实现小顶堆的话只需要修改一下heapkeep函数的判断条件。
java实现堆结构的更多相关文章
- Java中堆内存和栈内存详解2
Java中堆内存和栈内存详解 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...
- Java中堆内存和栈内存详解
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- Java程序猿从笨鸟到菜鸟之(九十二)深入java虚拟机(一)——java虚拟机底层结构具体解释
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在曾经的博客里面,我们介绍了在java领域中大部分的知识点,从最基础的java最基本的语法 ...
- Java中堆与栈
简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...
- Java中堆(heap)和栈(stack)的区别
简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...
- JVM基础系列第6讲:Java 虚拟机内存结构
看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...
- Java SE之Java中堆内存和栈内存[转/摘]
[转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...
- 翻译Java虚拟机的结构
英文原版: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 直接谷歌翻译: Java SE规范 > Java虚拟机 ...
- JAVA之堆内存和栈内存的差别
欢迎转载.请附上出处: http://blog.csdn.net/as02446418/article/details/47007975 笔者近期在准备面试的时候又一次看了一些JAVA基础的知识,以下 ...
随机推荐
- Java 8新特性探究(二)类型注解和重复注解
本文将介绍java 8的第二个特性:类型注解. 注解大家都知道,从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什 ...
- Socket层实现系列 — 信号驱动的异步等待
主要内容:Socket的异步通知机制. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 概述 socket上定义了几个IO事件:状态改变事件.有数据可读事 ...
- OpenCV空洞填充算法
讨论帖: http://bbs.csdn.net/topics/391542633 在Matlab下,使用imfill可以很容易的完成孔洞填充操作,感觉这是一个极为常用的方法,然而不知道为什么Op ...
- android 之ViewStub
在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...
- OpenCV矩阵运算
矩阵处理 1.矩阵的内存分配与释放 (1) 总体上: OpenCV 使用C语言来进行矩阵操作.不过实际上有很多C++语言的替代方案可以更高效地完成. 在OpenCV中向量被当做是有一个维数为1的N维矩 ...
- OAF 开发TAB页
TAB页 2013年1月17日 21:31 当查询结果列数比较多的时候,往往一页显示不下,在FORM的情况下,我们往往会用Tab页的方法解决.那么在OAF如何制作TAB页呢?下面的教程将介绍如何制作一 ...
- SpriteBuilder全屏弹出菜单的特殊效果
但是等一下!这里可以有更多.对于全屏的弹出菜单,你可以在显示弹出全屏菜单时朦胧化背景的level视图. 通过修改SpriteBuilder中的color节点的Color属性(比如修改为black)和O ...
- C语言可变参实现参数累加返回
C语言可变参的作用真的是非常大,自从发表了可变参如何实现printf,fprintf,sprintf的文章以来,便有不少博友私信问我实现的机制,我也解释了相关的知识点.今天,我们借着这个机会,再来举一 ...
- 让opencv程序在没有安装opencv的电脑上运行
经常需要把用opencv写的程序拿到没有装opencv的电脑上去运行和演示,要让opencv程序脱离opencv环境,一般有两种方法: 一种是动态链接opencv,即把相应的dll拷贝到exe所在目录 ...
- DTN学习,theONE模拟器网络相关资料整理
下面是一个百度空间的: http://hi.baidu.com/jensenliao 博客园的一篇博客:theONE模拟器简介(主要讲述,软件配置,软件结构) http://www.cnblogs.c ...