Java实现堆(最大堆)

article/2025/11/7 13:29:39

1、什么是堆

现在有这么一个需求,设计一个结构,满足两个操作要求:

  1. 删除时,返回该结构的最大值或者最小值的元素
  2. 往结构中新增元素

问题:如何组织优先这种结构?

  • 一般数组、链表?
  • 有序数组或者链表?
  • 二叉搜索树或者AVL树?
结构插入删除
数组插到数组尾部时间复杂度O(n)查找最大或者最小值,删除后需要移动元素,时间复杂度O(2n)
链表插入到链表头部,时间复杂度 O(1)查找最大或者最小值,删除结点,时间复杂度O(n)
有序数组查找插入位置,插入后移动元素并且插入,时间复杂度O(2n)删除尾部,时间复杂度O(1)
有序链表查找插入位置,插入节点,时间复杂度O(n)删除首或者尾节点,时间复杂度O(1)
二叉搜索树查找节点位置,插入,时间复杂度为log2(n),找到根节点右子树最大的节点,时间复杂度为O(n)

如果在用二叉树结构

  1. 删除的时候怎么设计?
  2. 插入又应该怎么设计?

堆:完全二叉树结构
在这里插入图片描述

堆的结构定义

public class Heap {Integer[] data;int capacity;   //堆容量int size; //堆中元素个数int max=100000; public Heap(){this.capacity = 10;this.data = new Integer[capacity+1];//定义"哨兵"为大于堆中所有可能元素的值data[0] = max;}public Heap(int capacity) {this.data = new Integer[capacity+1];this.capacity = capacity;data[0] = max;}
}

2、最大堆的插入

  1. 首先在堆尾部(数组的尾部)
  2. 判断插入节点是否大于父节点,如果大于的话,插入节点和父节点互换位置,重复上述操作,直到出现插入节点小于父节点或者插入节点一路互换后变成根节点。
 public void insert(int value) {if (this.size==capacity) {this.data = (Integer[]) Arrays.copyOf(this.data, capacity * 2);}data[++size] = value;for (int i=size;i>0;i/=2) {if (data[i]>data[i/2]) {swap(data,i,i/2);	//数组中两数交换}}}

3、最大堆的删除

  1. 首先保存要返回的根节点
  2. 保存堆最后一个节点为X
  3. 从根节点往下遍历,如果根节点的左右儿子有大于X的,那么左右儿子中大的值设置为根节点,将左右儿子中较大的节点作为该节点的儿子节点的根节点,重复上述判断。最后如果出现X大于根节点的左右儿子节点或者根节点为叶子节点时,将当前根节点设置为X。
 private Integer delete() {if (size==0){return null;} else {int parent,chrild = 0;int maxValue = data[1];int X = data[size--];for (parent = 1; parent<=size; parent = chrild) {chrild = parent*2;if (chrild!=size && (data[chrild]<data[chrild+1])) {chrild++;}if (X>data[chrild]) {break;} else {data[parent] = data[chrild];}}data[parent] = X;data[size+1] = null;return maxValue;}}

4、最大堆的建立

从堆最后一位的父节点开始,将该节点作为根节点,把该节点的堆调整为最大堆,然后依次取前一位父节点,直到根节点调整结束。

	public void createMaxHeap(int[] heap) {for ( int i=size/2; i>0;i/=2) {percDown(heap,i);}}private void percDown(int[] heap, int i) {int parent,chrild = 0;int X = data[i];for (parent = 1; parent<=size; parent = chrild) {chrild = parent*2;if (chrild!=size && (data[chrild]<data[chrild+1])) {chrild++;}if (X>data[chrild]) {break;} else {data[parent] = data[chrild];}}data[parent] = X;}

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

相关文章

五、Java堆

Java堆 对于Java应用程序来说&#xff0c;Java堆 是虚拟机所管理的内存中最大的一块。堆&#xff0c;是被所有线程共享的一块内存区域&#xff0c;在虚拟机启动时创建。堆&#xff0c;唯一的目的就是存放对象实例&#xff0c;Java世界中“几乎”所有的对象实例都是在这里分配内…

java中的堆实现

java中的堆实现 完全二叉树&#xff1a;叶子结点只能出现在最下层和次下层&#xff0c;且最下层的叶子结点集中在树的左部。即除了最后一层&#xff0c;其他层的节点个数都是满的&#xff0c;而且最后一层的叶子节点必须靠左。 如图&#xff1a; 二叉堆&#xff1a;必须是完…

[JAVA数据结构]堆

目录 1.堆的概念 2.堆的创建 3.堆的插入与删除 3.1堆的插入 3.2堆的删除 1.堆的概念 如果有一个关键码的集合K {k0&#xff0c;k1&#xff0c; k2&#xff0c;…&#xff0c;kn-1}&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中&#xff0c;…

堆的Java实现

一.概念 堆是计算机科学中一类特殊的数据结构的统称&#xff0c;堆通常可以被看做是一棵完全二叉树的数组对象。 堆的特性&#xff1a; 它是完全二叉树&#xff0c;除了树的最后一层结点不需要是满的&#xff0c;其它的每一层从左到右都是满的&#xff0c;如果最后一层结点不是…

堆的创建---java

目录 1、堆的概念 2.堆的存储方式 3、堆的创建 3.1、堆向下调整 3.2、堆的创建 1、堆的概念 如果有一个关键码的集合K {k0&#xff0c;k1&#xff0c; k2&#xff0c;…&#xff0c;kn-1}&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中&…

【堆】堆的实现(Java)

今天学习堆这种数据结构。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质&#xff1a; 堆中某个结点的值总是不大于或不小于其父结点的值&#xff1b;堆总是一棵完全二叉树。 将根结点最大的堆叫做最大堆或大根堆&#xff0c;根结点最小的堆叫做最小堆或小根堆…

Java之堆和堆排序

目录 一.什么是堆 1.基本介绍 2.堆的实现方式 二.最大堆的实现 1.最大堆 2.思路分析 0.基础操作 1.添加上浮操作 2.删除下沉操作 3.将数组堆化操作 2.代码实现 三.堆排序 1.什么是堆排序 2.思路分析 3.代码实现 一.什么是堆 1.基本介绍 堆是一种数据结构&#…

六、Java堆

一、堆的核心概述 1、概述 1、堆针对一个JVM进程来说是唯一的&#xff0c;也就是一个进程只有一个JVM&#xff0c;但是进程包含多个线程&#xff0c;他们是共享同一堆空间的。 2、一个JVM实例只存在一个堆内存&#xff0c;堆也是Java内存管理的核心区域。 3、Java堆区在JVM启动…

Java数据结构-堆

目录 一、简介二、堆的实现&#xff08;1&#xff09;堆的插入&#xff08;2&#xff09;删除根节点&#xff08;3&#xff09;上浮操作① 大根堆的上浮② 小根堆的上浮 &#xff08;4&#xff09;下沉操作① 大根堆的下沉② 小根堆的下沉 &#xff08;5&#xff09;堆的构造&a…

JVM JAVA中的堆

堆的核心概述&#xff1a; 一个进程对应一个JVM的实例&#xff0c;一个JVM实例中只有一个运行时数据区&#xff0c;里面只有一个方法区和堆&#xff0c;一个进程的多个线程共享方法区和堆&#xff0c;那就要考虑线程的安全问题。 每个线程各有一套程序计数器、本地方法栈、虚拟…

Java堆是如何划分的?

写在前面 本文隶属于专栏《100个问题搞定Java虚拟机》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和文献引用请见100个问题搞定Java虚拟机 解答 Java 虚拟机将堆划分为…

数据结构-堆和堆的Java实现

1. 定义 堆&#xff08;英语&#xff1a;heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质&#xff1a; 1.堆中某个节点的值总是不大于或不小于其父节点的值&#xff1b; 2.堆总是一棵完全二叉树。 常见的堆有二…

Java数据结构之堆(Heap)

文章目录 一、基本概念二、上浮操作(siftUp)三、下沉操作(siftDown)四、数组堆化五、实现大根堆 提示&#xff1a;以下是本篇文章正文内容&#xff0c;Java系列学习将会持续更新 一、基本概念 堆在逻辑上就是一棵完全二叉树。堆在物理上是储存在数组中。满足任意根节点值>…

JVM--堆

45. JVM--堆 1. 堆的核心概述 一个进程对应一个JVM的实例&#xff0c;一个JVM实例中只有一个运行时数据区&#xff0c;里面只有一个方法区和堆&#xff0c;一个进程的多个线程共享方法区和堆&#xff0c;那就要考虑线程的安全问题。 每个线程各有一套程序计数器、本地方法栈、虚…

java中的堆

文章目录 一、堆的分类二、详述Java堆中各个区域1、堆大小2、新生代 ( Young ) 的划分3、工作原理4、GC日志 一、堆的分类 Java 中的堆是 JVM 管理的最大的一块内存空间&#xff0c;主要用于存放Java类的实例对象 其被划分为两个不同的区域&#xff1a;新生代 ( Young )和老年…

Java数据结构--堆

一.堆的定义及本质 要知道在Java中&#xff0c;堆是以优先级队列来表示的。因此学会了堆&#xff0c;我们也就学会优先级队列 1.堆的定义 当一颗二叉树的每个节点都大于等于它的两个子字节时&#xff0c;它被称为堆有序。而堆是一组能够用堆有序的完全二叉树排序的元素&…

Java数据结构之堆

堆的概念 堆逻辑上是一棵完全二叉树堆物理上是保存在数组中满足任意结点的值都大于其子树中结点的值&#xff0c;叫做大堆&#xff0c;或者大根堆&#xff0c;或者最大堆反之&#xff0c;则是小堆&#xff0c;或者小根堆&#xff0c;或者最小堆堆的基本作用是快速找集合中的最…

常用三极管引脚定义

给大家总结了常用封装的三极管的引脚定义 配套的视频讲解 常用三极管引脚定义

常用电子器件 ——三极管

说明&#xff1a;   本文章旨在总结备份、方便以后查询&#xff0c;由于是个人总结&#xff0c;如有不对&#xff0c;欢迎指正&#xff1b;另外&#xff0c;内容大部分来自网络、书籍、和各类手册&#xff0c;如若侵权请告知&#xff0c;马上删帖致歉。   QQ 群 号&#xf…

三极管开关特性

三极管在我们数字电路和模拟电路中都有大量的应用&#xff0c;在我们开发板上也用了多个三极管。在我们板子上的 LED 小灯部分&#xff0c;就有这个三极管的应用了&#xff0c;图 3-5 的 LED 电路中的 Q16就是一个 PNP 型的三极管。 图 3-5 LED 电路 三极管的初步认识 三极管…