[JAVA数据结构]堆

article/2025/11/7 13:25:34

目录

1.堆的概念

2.堆的创建

3.堆的插入与删除

3.1堆的插入

3.2堆的删除


1.堆的概念

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆

 注意:堆是一棵完全二叉树

2.堆的创建

        在堆这种数据结构中,可以看成每三个元素构成的一个子树为单位来观察。所以我们要调节的是每一个子树的父亲节点与孩子节点之间的关系

        对于大根堆,我们需要维护父亲节点比孩子节点都大

        对于小根堆,我们需要维护父亲节点比孩子节点都小

        我们可以从最后一棵子树开始,先得到其父亲节点与孩子节点,再比较其关系进行位置上的调整。调整完此子树后,因为我们是从下往上开始遍历,变动了一棵树的位置就可能影响到其他子树的关系,所以我们需要维护其下方子树也应为一个大/小根堆

        需要将父亲节点的位置移动到孩子节点的位置,孩子节点移动到下一棵子树的孩子节点位置中

对于父亲节点与孩子节点的数组下标关系为:

(在找孩子节点的时候,因为堆是一棵完全二叉树的原因,可能没有右孩子。所以我们首先搜寻的是其左孩子节点)

parent:父亲节点的下标

child:左孩子节点的下标

parent = (child - 1) /  2;

chile = parent * 2 + 1;

下面是建立大根堆的图演示 

 ​​

代码演示:

import java.util.Arrays;public class Heap {public int[] elem;public static int usedSize;public Heap(int[] elem) {this.elem = new int[10];//初始长度为10,后面可以考虑扩容}//创建一个大根堆public void createHeap(int[] array){//首先要放到elem数组中,还可以得到其元素个数for(int i = 0; i < array.length; i++){this.elem[i] = array[i];usedSize++;}//开始创建大根堆//首要要找到其最后一棵子树的父亲节点//parent = (child - 1) / 2//最后一棵子树,肯定包含有数组中的最后一个节点//所以我们可以通过最后一个元素的下标来得到父亲节点的下标//从最后一棵子树开始,遍历每一颗子树,每一颗子树父亲节点在数组中相邻//直到父亲节点的下标小于0下标for(int parent = (usedSize - 1 - 1) / 2; parent >= 0; parent--){//我们将维护子树状态的方法称为向下调整shiftDown(parent,usedSize);}}//向下调整private void shiftDown(int parent, int len) {//向下调整是,维护子树的状态//因为调整了节点的关系,可能也会影响其他子树,所以要调整与此子树相关的下方的子树//可以用过parent = child的方法来跳跃到其他子树//直到child越界int child = parent * 2 + 1;//得到左子树的下标while(child < len){//第一步,查看左右孩子节点的大小关系//按需则取,再与父亲节点比较//当然是在确保拥有右孩子的前提下if(child + 1 < len && elem[child] < elem[child + 1]){//因为我们创建的是大根堆//在右孩子比左孩子大的时候,我们的child位置需要跳转到右孩子child = child + 1;//child的位置从左孩子跳到右孩子}//再与父亲节点比较if(elem[child] > elem[parent]){//交换int tmp = elem[child];elem[child] = elem[parent];elem[parent] = tmp;//向下调整//父亲节点跳转到孩子节点//孩子节点根据跳转后的父亲节点的下标进行转换parent = child;child = parent * 2 + 1;}else{break;//因为我们是从下往上调整的,只要此树满足了大根堆//就不需要变动节点的位置,也就意味着不会影响已经调整好了的其他子树//所以可以直接break}}}public static void main(String[] args) {int[] array = {1,5,3,7,8,6};Heap heap = new Heap(array);heap.createHeap(array);System.out.println(Arrays.toString(heap.elem));}
}

 结果为:

3.堆的插入与删除

3.1堆的插入

        堆的插入是插在队尾的,即当作此数组的最后一个元素。

        插入一个元素后,要维持其依然为一个大/小根堆,所以需要调整。但元素是在队尾的,就不能用之前的向下调整了,此处运用的是向上调整。将插入的元素逐步向上转移,安插到一个合适的位置。

以大根堆为例:

 代码演示:

    public void push(int val){if(isFull()){//如果满了就要扩容elem = Arrays.copyOf(elem,2*elem.length);}this.elem[usedSize++] = val;shiftUp(usedSize - 1);}public void shiftUp(int child){int parent = (child - 1) / 2;//实际上就是把新插入的数值当成child,一直推着其往上移动,直到找到一个合适的地方while(child > 0){if(elem[child] > elem[parent]){int tmp = elem[child];elem[child] = elem[parent];elem[parent] = tmp;child = parent;parent = (child - 1) / 2;}else{break;}}}public boolean isFull() {return usedSize == elem.length;}

3.2堆的删除

        关于堆的删除,堆只能删除其最后一个元素。

        首先把最后一个元素放到0下标即堆顶的位置,再使usedSize-1,达到删除的效果.

        为了维持堆的特性,我们将新换到堆顶的元素使用向下调整,将其安插到合适的地方

    public void poll() {if(empty()) {throw new RuntimeException("堆为空");}//交换最后一个元素和第一个元素的位置int tmp = elem[0];elem[0] = elem[usedSize-1];elem[usedSize-1] = tmp;usedSize--;//总元素-1,无法读取,达到删除的效果shiftDown(0,usedSize);//将新换到堆顶的元素向下调整}public boolean empty() {return usedSize == 0;}


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

相关文章

堆的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 电路 三极管的初步认识 三极管…

常用三极管入门级电路设计(如何选型和搭电路?)

转自&#xff1a; 常用的三极管电路设计-电阻到底是怎么选的&#xff08;修正后&#xff09;-面包板社区 硬件基础知识---如何设计一个三极管放大电路_学无止境的专栏-CSDN博客_uce怎么算 今天的内容超级简单&#xff0c;主要给硬件新手写点东西&#xff0c;关于三极管实用方…

三极管相关知识点

1.两种类型的三极管图示如下&#xff0c;基极&#xff08;Base&#xff09;、集电极&#xff08;Collector&#xff09;和发射极&#xff08;Emitter&#xff09;&#xff0c;等效二极管电路如图所示 2.三极管的几种工作状态&#xff0c; 3.三极管做开关功能时&#xff0c;工…

三极管的一些基本知识

导通条件 NPN型三极管的导通条件是C点电位>B点电位>E点电位&#xff0c;三极管饱和导通的条件是Ub>Ue,Ub>Uc。 PNP型三极管的导通条件是E点电位>B点电位>C点电位&#xff0c;三极管饱和导通的条件是Ue>Ub,Uc>Ub。 NPN型三极管 1、定义&#xff1a; …