堆的操作(Java)

article/2025/9/25 12:16:50

文章目录

  • 1.堆的存储方式
  • 2.堆的创建
    • 2.1向下调整
    • 2.2向上调整
  • 3.堆的操作
    • 3.1元素插入堆
    • 3.2取堆顶元素
    • 3.3删除堆顶元素

1.堆的存储方式

由堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来存储堆。
在这里插入图片描述
注意:
对于非完全二叉树,则不适合使用顺序的方式进行存储。因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低。
然后针对这种存储方式,要对完全二叉树进行操作的时候,直接取下标即可:
1)如果i为0,则i表示的结点为根节点,否则i的双亲结点为(i-1)/2;
2)如果2i+1小于结点个数个数,则结点的左孩子下标为2i+1,否则没有左孩子;
3)如果2i+2小于结点个数,则结点i的右孩子下标为2i+2,否则没有右孩子。

2.堆的创建

堆的创建:给定一个数组,整理成堆这样的结构(转换完全二叉树并且使用数组来存储,满足下标条件,满足下标关系,还满足堆的条件)

2.1向下调整

向下调整的思路(以大堆为例):
从待调整的位置出发作为父节点,然后根据下标关系得到他的子树,然后找到他的子树的最大值,然后他的孩子结点指向左右子树的最大值,然后拿他的最大值与父节点的值做比较,若不满足堆的大小,则交换两个元素。

public class Heap {//向下调整是创建堆的一个核心操作//前提条件是当前被调整的左右子树都是堆//方法参数中给出堆表示当前元素有效位置的大小//可以通过arr.length,这个大小是整个大小//index是表示从这个位置开始向下进项调整private void shiftDown(int [] arr ,int size,int index){//调整过程中,从待调整的位置出发//取出该结点的左右子树(通过下标换算的方式)//若当前是大堆,找出左右孩子中较大的值int parent=index;int child=2*parent+1;while(child<size){//需要找到左右子树中较大的值//左右子树下标差1if(child+1<size&&arr[child+1]>arr[child])  {child=child+1;}//当左右子树遍历执行完之后,child就指向左右子树中较大的值//拿父节点和当前较大的结点去比较,看是否满足大堆的要求if(arr[parent]<arr[child]){//不满足大堆的要求,交换两个元素int tmp=arr[parent];arr[parent]=arr[child];arr[child]=tmp;}else{break;}parent=child;child=2*index+1;}}//建堆操作public void createHeap(int [] arr){//基于向下建堆的操作;//从最后一个结点的父节点往前,对于每个下标从后往前向下调整即可//或者最后一个非叶子结点for(int i=(arr.length-1-1)/2;i>=0;i--){shiftDown(arr,arr.length,i);}}
}

2.2向上调整

向上调整的基本思路(大堆为例):
首先从当前结点出发作为子节点,然后根据下标的关系表达找到他的父节点,如果双亲比孩子大,则满足堆的性质,调整结束,反之,将两个结点进行交换。然后将结点向上移动。

public  static void shiftUp(int [] arr,int size,int index){int child=index;int parent=(child-1)/2;//如果child为0,已经调整到最上面了while(child>0){if(arr[parent]<arr[child]){//不符合大堆要求//交换两个元素int tmp=arr[parent];arr[parent]=arr[child];arr[child]=tmp;}else{break;}child=parent;parent=(child-1)/2;}}

3.堆的操作

3.1元素插入堆

堆的插入总共需要两个步骤:
1)先将元素放在数组末尾(空间不够时可以扩容)
2)然后将新插入的结点进行向上调整,直到满足堆的条件即可。

public  static void shiftUp(int [] arr,int size,int index){int child=index;int parent=(child-1)/2;//如果child为0,已经调整到最上面了while(child>0){if(arr[parent]<arr[child]){//不符合大堆要求//交换两个元素int tmp=arr[parent];arr[parent]=arr[child];arr[child]=tmp;}else{break;}child=parent;parent=(child-1)/2;}}private int [] arr=new int[100];private int size=0;//往堆中插入元素public void offer(int val){if(size>=arr.length) {return ;}arr[size]=val;size++;//把最后的元素进行向上调整shiftDown(arr,size,size-1);}

3.2取堆顶元素

堆顶元素是第一个元素,结果是显然的。

public class Heap{
//获取堆顶元素public Integer peek(){if(size==0){return null;}return arr[0];}}

3.3删除堆顶元素

基本思路:
采用移形换影,拿0号元素(要删除的元素)和最后一个元素交换,然后size–,然后进行向下调整。

//删除元素(一定是删除堆顶元素)public Integer poll(){if(size==0){return null;}//拿0号元素(要删除的元素)和最后一个元素交换//size--//然后向下调整int result=arr[0];//交换0号元素和size-1项元素int tmp=arr[0];arr[0]=arr[size-1];arr[size-1]=tmp;size--;shiftDown(arr,size,0);return result;}

http://chatgpt.dhexx.cn/article/yyglcxwa.shtml

相关文章

[Java]堆

目录 一、堆的概念 二、大小根堆的建立 三、 堆的调整 1. 向下调整 2. 向上调整 三、堆的删除与插入 一、堆的概念 堆可以看做一个完全二叉树&#xff0c;如果有一个关键码的集合K {k0&#xff0c;k1&#xff0c; k2&#xff0c;…&#xff0c;kn-1}&#xff0c;把它的所…

JVM-堆

文章目录 堆&#xff0c;是运行是数据区的一部分堆内存分区&#xff1a;JAVA堆区细分&#xff1a; 设置堆内存大小与OOM设置堆空间大小 OOM Outof Memory Error 举例!!!图解对象分配过程Minor GC、Major GC、Full GC年轻代 GC&#xff08;Minor GC&#xff09;触发机制老年代 G…

jvm堆大小的设置

问题引入&#xff1a; -Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio3&#xff0c;,其最小内存值和Survivor区总大小分别是&#xff08;10240m 2048m&#xff09;&#xff1b; 解析&#xff1a; -Xmx&#xff1a;最大堆大小 -Xms&#xff1a;初始堆大小 -Xmn:年轻…

如何修改java中堆、栈空间的默认大小

1、修改堆、栈空间大小的命令 在命令行中输入java -X可以得到设置java堆大小和栈大小的命令 2、修改java运行时的堆和栈空间 进入界面后 按AltV 3、检验堆空间修改 3.1 测试类 public class StackTest {public static void main(String[] args) {//返回Java虚拟机中的堆内存…

java 堆设置

Young&#xff1a;主要是用来存放新生的对象。&#xff08;Eden、survivorSpaces(from、To)&#xff09; Old&#xff1a;主要存放应用程序中生命周期长的内存对象。 Permanent&#xff1a;是指内存的永久保存区域&#xff0c;主要存放Class和Meta的信息,Class在被 Load的时候…

Java堆内存设置

堆内存设置 原理 JVM堆内存分为2块&#xff1a;永久空间和堆空间。 永久即持久代&#xff08;Permanent Generation&#xff09;&#xff0c;主要存放的是Java类定义信息&#xff0c;与垃圾收集器要收集的Java对象关系不大。Heap {Old NEW {Eden&#xff0c;from&#xff0…

OBEX(一)

一、概述 1、OBEX v2.0&#xff08;v2.0版本开始OBEX直接在L2CAP上传输&#xff0c;v2.0版本以前OBEX在RFCOMM上传输&#xff09; 2、OBEX即Object Exchange Protocol&#xff0c;对象交换协议 3、OBEX协议是典型的client/server request-response模型 4、OBEX v2.0蓝牙协议…

利用docker部署oxidized网络设备备份系统

随着网络设备的增多,通过人手备份网络设备倍感压力,而且效率低。有编程基础的人可能会通过Python的parimiko 或者netmiko 连接到设备操作 把文件通过ftp 上传到FTP服务器, 在通过定时任务,定期自动备份。这个应该是现阶段主流非人民币网络玩家的最优解决方案。 今天我们来看看…

网络自动化运维第一篇 自动化备份网络配置

网络设备厂商众多&#xff0c;各种安全厂商&#xff0c;网络厂商&#xff0c;负载均衡厂商&#xff0c;如果想实现自动化备份配置&#xff0c;可以自己写python脚本。如果网络设备厂商多&#xff0c;自己写python 非常耗费时间精力。偶然在网上发现了oxidized 非常好用&#xf…

.odex文件的反编译

0x00 问题呈现 在分析某手机自带应用时&#xff0c;为了在JEB中反编译&#xff0c;将其adb pull到了电脑上。解压后发现如下文件&#xff1a; APK解压目录列表 惊奇的发现该APK包中没有dex文件&#xff0c;一开始特别疑惑没有dex文件&#xff0c;也就是没有代码&#xff0c;那…

ZeroDivisionError: integer division or modulo by zero

这里的错误就是由于数据集太小。 # 2. Split into train / validation partitionsn_val int(len(dataset) * val_percent)n_train len(dataset) - n_val#我这里是刚好有10张数据集然后其中一张被拆分为验证集导致训练集太小&#xff0c;从而报错。

反编译odex

需要工具&#xff1a; 1、baksmali-x.x.x.jar2、smali-x.x.x.jar工具下载&#xff1a;https://bitbucket.org/JesusFreke/smali/downloads/ 步骤&#xff1a; 1、odex转smali&#xff1a; java -jar “D:\google\tool\mony_tool\baksmali-2.2.1.jar” deodex SystemUI.odex -…

ZeroDivisionError:Integer division or modulo by zero

docker环境下&#xff0c;多GPU训练 方式&#xff1a;采用nvidia-docker创建容器 另&#xff1a; 在用sudo无法解决sh文件的pemission denied问题时&#xff0c;采用bash替代sudo

deactive(Deactive breakpoint)

deactive怎么译&#xff1f; de-active 原指吊销, 计算机的专用词叫 "去活". 多指停止某指令.吊销&#xff0c;不激活&#xff0c;关闭 三星bc01指令代码 三星手机总复位&#xff0c;在待机状态下输入*2767*3855#需要专门的智能仪器才可以解开手机密码忘记了 一般普…

Oxidized-20180912-docker 版本的网络设备备份系统

Problem Oxidized 非常好用&#xff0c;基本兼容所有网络设备的备份&#xff0c;但是有一个小小小小的问题&#xff0c;就是在 Linux 环境下&#xff0c;默认安装的 Ruby 版本问题为其在离线情况下的安装增添了很多的麻烦和限制。 于是轻量级的 docker 成了不二的选择。 &am…

Oxidized-最好用的网络设备备份系统(三)-双机自动备份

oxidized备份网络配置默认路径为 /root/.config/oxidized/group group分别是不同设备分组 group1 group2 group3 group4 双机自动备份思路: 制作将需要备份的数据先备份到back/bak目录下,再通过打包gz格式放到backup目录下,然后通过远程传输,上传到备份服务器的/usr/…

cas:27025-41-8 Glutathione oxidized氧化型谷胱甘肽 活性氧抑制剂

cas:27025-41-8 Glutathione oxidized氧化型谷胱甘肽 活性氧抑制剂 中文名称&#xff1a;氧化型谷胱甘肽 英文名称&#xff1a;Glutathione oxidized 分子量&#xff1a;612.63 性状&#xff1a;Solid 分子式&#xff1a;C20H32N6O12S2 cas:27025-41-8 别称&#xff1a;…

Oxidized-最好用的网络设备备份系统(二)

上文回顾 书接上文, 看完上篇文章的同学相信大家对这个”oxidized” 有了初步的了解, 有同学对config 配置有些疑惑 我这里简单介绍一下。 --- username: username : 用户名 这个参数不用改,会从router.db读取. password: password : 密码 这个参数也不用改,会从router.db…

整理了一下oxidized+mysql+gitlab,感觉很好用,做个记录

安装oxidized 安装ruby yum install centos-release-scl yum install rh-ruby23 rh-ruby23-ruby-devel scl enable rh-ruby23 bash 安装依赖关系 yum install make cmake sqlite-devel openssl-devel libssh2-devel ruby gcc ruby-devel libicu-devel gcc-c 安装oxidized gem…

docker oxidized时区问题,时间显示不是北京时间问题的解决办法

问题描述&#xff1a;oxidized web界面时间显示&#xff0c;默认显示UTC时间&#xff0c;为北京时间-8个小时 问题原因&#xff1a;ruby语言的时间直接获取的UTC时间 出现版本&#xff1a;oxidized 0.28.0 问题解决&#xff1a; docker exec -it oxidized /bin/bashvim /var/l…