JDK源码研究PriorityQueue(优先队列)

Java反序列化漏洞CC4链原理与实战:从TransformingComparator到命令执行 Java反序列化漏洞是安全领域的核心议题,其本质在于攻击者通过精心构造的序列化数据,在目标系统反序列化过程中控制程序执行流。这类漏洞通常利用Java对象序列化机制与特定类库(如Apache Commons Collections)中可被串联的回调方法,形成完整的攻击链(Gadget Chain)。其技术价值在于能够绕过常规安全边界,实现远程代码执行(RCE),对Web应用、中间件等构成严重威胁。在众多利用链中,CC链家族因其在Apache Commons Collections库中的广泛存在而备受关注。针对 阅读详情

Priority Queue

 

目的:

通过对JDK源码的分析,进一步了解堆和优先队列,体会JDK源码的优美之处。

目录:

        1:概念

        2:源码结构

        3:方法分析

概念:

概念1:堆

堆,n个关键字序列K1,K2,…,Kn,当且仅当该序列满足如下性质称为堆

ki≤K2i且ki≤K2i+1(最小堆) 或 (2)Ki≥K2i且ki≥K2i+1 (最大堆)

堆一般用顺序存储结构存储(数组),但逻辑上可以认为是一个完全二叉树。

概念2:优先队列

优先队列,不同于普通的遵循FIFO(先进先出)规则的队列,每次都选出优先级最高的元素出队,优先队列里实际是维护了这样的一个堆,通过堆使得每次取出的元素总是最小的(用户可以自定义比较方法,相当于用户设定优先级)。

 

源码结构

   字段

 

Java代码   收藏代码
  1. //默认初始化大小  
  2. private static final int DEFAULT_INITIAL_CAPACITY = 11;  
  3. //堆  
  4. private transient Object[] queue;  
  5. //当前大小  
  6. private int size = 0;  
  7. //比较器  
  8. private final Comparator<? super E> comparator;  
  9. //修改次数(增、删、改、查)  
  10. private transient int modCount = 0;  

   方法    

Java代码   收藏代码
  1. //增加  
  2. public boolean add(E e)   
  3. //出队(不删除)  
  4. public E peek()  
  5. //出队(删除)  
  6. public E poll()  
  7. //删除  
  8. public boolean remove(Object o)  
  9. //是否包含某元素  
  10. public boolean contains(Object o)  
  11. //清空  
  12. public void clear()  
  13. //扩容  
  14. private void grow(int minCapacity)  
  15. //查找  
  16. private int indexOf(Object o)  

方法分析

1:增加

堆在增加元素后,需要进行调整才能维护其最大堆或者最小堆的性质,下面以最小堆为例:


       增加元素26,默认是从队尾增加,即直接添加到数组最后。下一步需要执行上滤。从上图可以看出,26比其父节点39小,因此两者交换位置;再次比较此时的26和其父节点30,30>26,调整位置,依次进行直到找到比26小的父节点,结束。

代码:

 add

Java代码   收藏代码
  1. public boolean add(E e) {  
  2.         return offer(e);  
  3.     }  

   可以看出,add方法实际上是全部委托给offer(E)

 

Java代码   收藏代码
  1.  public boolean offer(E e) {  
  2.     if (e == null)  
  3.         throw new NullPointerException();  
  4.     modCount++;  
  5.     int i = size;  
  6.     //检查容量(扩容)  
  7.     if (i >= queue.length)  
  8.         grow(i + 1);  
  9.     //改变size  
  10.     size = i + 1;  
  11.     //调整  
  12.     if (i == 0)  
  13.         queue[0] = e;//无父节点 ,直接赋值  
  14.     else  
  15.         siftUp(i, e);//有父节点,需要上滤  
  16.     return true;  
  17. }  

    第1步:判空

Java代码   收藏代码
  1. if (e == null)  
  2.     throw new NullPointerException();  

    第2步:改变大小和扩容

Java代码   收藏代码
  1. modCount++;  
  2. int i = size;  
  3. if (i >= queue.length)  
  4.     grow(i + 1);  
  5. size = i + 1;  

   第3步:添加元素并上滤

Java代码   收藏代码
  1. if (i == 0)  
  2.     queue[0] = e;  
  3. else  
  4.     siftUp(i, e);  

  从上面的3步中可以看出,实际上关键的步骤是:grow 和 siftUp

  grow方法

Java代码   收藏代码
  1. private void grow(int minCapacity) {  
  2.     if (minCapacity < 0) // overflow  
  3.         throw new OutOfMemoryError();  
  4.     int oldCapacity = queue.length;  
  5.     // Double size if small; else grow by 50%  
  6.     int newCapacity = ((oldCapacity < 64) ? ((oldCapacity + 1) * 2)  
  7.             : ((oldCapacity / 2) * 3));  
  8.     if (newCapacity < 0) // overflow  
  9.         newCapacity = Integer.MAX_VALUE;  
  10.     if (newCapacity < minCapacity)  
  11.         newCapacity = minCapacity;  
  12.     queue = Arrays.copyOf(queue, newCapacity);  
  13. }  

1:扩容方式是:

   当前队列大小queue.length<64,则增加一倍容量;反之则增加一半容量。

 2:调用Arrays的copyOf函数 ,实际上调用了该函数

  

 这是个native方法。(注意,该方法只是浅克隆)

siftUp 方法

Java代码   收藏代码
  1. private void siftUp(int k, E x) {  
  2.     if (comparator != null)  
  3.         siftUpUsingComparator(k, x);  
  4.     else  
  5.         siftUpComparable(k, x);  
  6. }  

根据不同的比较方式,采取不同比较策略。

下面以使用默认comparator的方式分析

Java代码   收藏代码
  1. private void siftUpComparable(int k, E x) {  
  2.     Comparable<? super E> key = (Comparable<? super E>) x;  
  3.     //k>0保证元素有父节点  
  4.     while (k > 0) {  
  5.         //父节点下标  
  6.         int parent = (k - 1) >>> 1;  
  7.         Object e = queue[parent];  
  8.         //如果比父节点大,不需要移动,结束  
  9.         if (key.compareTo((E) e) >= 0)  
  10.             break;  
  11.         //父节点元素下移  
  12.         queue[k] = e;  
  13.         //改变k的位置  
  14.         k = parent;  
  15.     }  
  16.     //找到key对一个的合适的位置k,赋值  
  17.     queue[k] = key;  
  18. }  

   可以看出,该方法是采用迭代的方式,找到元素x的位置。

Java代码   收藏代码
  1. int parent = (k - 1) >>> 1;  
  2. Object e = queue[parent];  

   通过无符号移位操作,取得父节点位置

Java代码   收藏代码
  1. if (key.compareTo((E) e) >= 0)  
  2.  break;  
  3.  queue[k] = e;  
  4.  k = parent;  

  此处采用了默认的comparator

  如果比父节点值大,结束。

   如果比父节点值小,父节点值下沉,K重新赋值,直到k=0或者k结点的值大于或等于parent结点值。

2:出队(不删除)

Java代码   收藏代码
  1. public E peek() {  
  2.     if (size == 0)  
  3.         return null;  
  4.     return (E) queue[0];  
  5. }  

 这个很简单,只是取出了其中的首位元素,但是并没有删除,不需要调整堆。

3:出队(删除最小元素)

出队过程

当最小元素14出队,从数组尾处取39赋值给队首。之后,进行和增加元素后相反的动作即下滤。

首先选出根节点(父节点)39的两个孩子结点中较小者,和39交换位置;当39找到新位置后,执行同种方法,如果孩子结点为null或者都比39大,则结束。

代码:

Java代码   收藏代码
  1. public E poll() {  
  2.     // 优先队列为空,返回null  
  3.     if (size == 0)  
  4.         return null;  
  5.     int s = --size;  
  6.     modCount++;  
  7.     // 取出队首  
  8.     E result = (E) queue[0];  
  9.     E x = (E) queue[s];  
  10.     // 队尾赋值为null  
  11.     queue[s] = null;  
  12.     // 判断是否执行下滤  
  13.     if (s != 0)  
  14.         siftDown(0, x);  
  15.     return result;  
  16. }  

 可以看出其中主要方法是siftDown方法

Java代码   收藏代码
  1. private void siftDown(int k, E x) {  
  2.     if (comparator != null)  
  3.     siftDownUsingComparator(k, x);  
  4.     else  
  5.     siftDownComparable(k, x);  
  6. }  

  同样,和上滤一样,是根据不同的comparator采取不同措施比较

Java代码   收藏代码
  1. private void siftDownUsingComparator(int k, E x) {  
  2.     // 计算非叶子节点元素的最大位置  
  3.     int half = size >>> 1;  
  4.    // 如果不是叶子结点  
  5.     while (k < half) {  
  6.         // 左孩子  
  7.         int child = (k << 1) + 1;  
  8.        // 默认使用左孩子的值  
  9.         Object c = queue[child];  
  10.         //右孩子  
  11.         int right = child + 1;  
  12.         /如果右孩子小于左孩子,c重新赋值为右孩子的值  
  13.         if (right < size &&  
  14.             comparator.compare((E) c, (E) queue[right]) > 0)  
  15.             c = queue[child = right];  
  16.        // c和key(父节点)比较,若父节点大,不需要移动,结束  
  17.         if (comparator.compare(x, (E) c) <= 0)  
  18.             break;  
  19.         queue[k] = c;  
  20.         //改变k的位置,向下移动  
  21.         k = child;  
  22.     }  
  23.     queue[k] = x;  
  24. }  

 如果自上向下调整的位置k大于half,说明该结点是叶子结点,直接将x元素赋值给queue[k].

如果自上向下调整的位置k小于half,则递归调整。首先取出左右孩子结点,并取两者中较小者赋值给c,然后比较c和当前k处元素key,如果key小,则结束。如果c大,则将k和c调换位置,经过多次迭代后,当x应该存放在叶子结点上或者x的值小于其左右孩子节点时终止

4:删除

  删除有两种情况:

    情况1:

  此处是执行下滤过程。

 情况2:

此处是执行上滤过程。

Java代码   收藏代码
  1. private E removeAt(int i) {  
  2.     assert i >= 0 && i < size;  
  3.     modCount++;  
  4.     int s = --size;  
  5.     // 如果是最后一个元素,直接赋值null  
  6.     if (s == i)  
  7.         queue[i] = null;  
  8.     else {  
  9.         // 取最后一个元素后,最后位置赋值为null  
  10.         E moved = (E) queue[s];  
  11.         queue[s] = null;  
  12.         // 执行下滤  
  13.         siftDown(i, moved);  
  14.         // 如果下滤后元素位置没变,说明moved是该子树最小元素;之后需要执行上滤  
  15.         // 上滤和下滤实际效果是只会执行其中一个  
  16.         if (queue[i] == moved) {  
  17.             siftUp(i, moved);  
  18.             if (queue[i] != moved)// iterator中会用到此处  
  19.                 return moved;  
  20.         }  
  21.     }  
  22.     return null;  
  23. }  

 如果删除的是最后一个元素,则将最后一个元素设为null

Java代码   收藏代码
  1. if (s == i)  
  2.     queue[i] = null;  

 如果删除的不是最后一个元素,取出最后一个元素,并将最后一个元素设为null。执行向下调整函数  siftDown.

Java代码   收藏代码
  1. E moved = (E) queue[s];  
  2. queue[s] = null;  
  3. siftDown(i, moved);  

 如果执行了下滤之后,如情况2,此时24并没有向下移动,此时说明需要进行上滤过程

Java代码   收藏代码
  1. if (queue[i] == moved) {  
  2.     siftUp(i, moved);  
  3.     if (queue[i] != moved)// iterator中会用到此处  
  4.     return moved;  
  5. }  

 5:clear:清除

这个很简单,只是遍历数组,删除(设为null)

Java代码   收藏代码
  1. public void clear() {  
  2.     modCount++;  
  3.     for (int i = 0; i < size; i++)  
  4.         queue[i] = null;  
  5.     size = 0;  
  6. }  

 6:contains:是否包含

这个过程实际上就是查找过程

Java代码   收藏代码
  1. public boolean contains(Object o) {  
  2. urn indexOf(o) != -1;  
  3. }  

 7:idnexOf :查找

Java代码   收藏代码
  1. private int indexOf(Object o) {  
  2. (o != null) {  
  3.         //遍历数组查询  
  4.         for (int i = 0; i < size; i++)  
  5.             //如果是自定义的元素,重写equals方法是很有必要的  
  6.             if (o.equals(queue[i]))  
  7.                 return i;  
  8.     }  
  9.     return -1;  
  10. }  

以上只是简单的分析了主要的方法,对于构造函数,实际上主要就是调用这几个方法,就没有再分析。有兴趣可以自行分析,相信会有所收获

Proxmox VE 8.4 GPU 直通实战:RTX 4090 单卡直通 Windows 11,解决 Code 43 与黑屏 本文详细介绍了在Proxmox VE 8.4中实现RTX 4090 GPU直通Windows 11的完整流程,包括硬件准备、BIOS设置、VFIO驱动配置以及解决Code 43与黑屏问题的具体方法。通过逐步指导,帮助用户高效完成显卡直通配置,提升虚拟化环境下的图形性能。 阅读详情

相关推荐

蓝桥杯Java A组国赛真题:工程能力的实战标尺

Java工程能力是后端开发的核心素养,其本质在于在资源约束(如内存128MB、时间1s)下构建健壮、可维护、可扩展的代码。这涉及JDK特性深度运用(如JDK 11的ConcurrentHashMap.newKeySet、HexFormat)、防御性编程习惯(输入校验、资源关闭、边界处理)以及算法的工程化落地(状态压缩、差分建模、时空平衡设计)。高频搜索词'java: outofmemoryerror: insufficient memory'和'java中数组越界异常'正折射出开发者在真实场景中对内存管理与

weixin_30326515的博客 641

java优先队列PriorityQueue中Comparator的用法

在使用java的优先队列PriorityQueue的时候,会看到这样的用法。 PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2){ ...

衣衫破旧 歌声温柔 8833

合宙Air780EP速连OneNET:AT+MQTT应用指南

本文详细讲解了合宙Air780EP使用AT指令通过MQTT接入OneNET的过程。

2401_82812461的博客 1390

并发编程之BlockingQueue(二)

前言:咱们扒光系列的第一篇文章已经对concurrent包中的三层结构的第一层和第二层做了解析,并且对第三层中的lock做了详细的代码分析,本篇博文将针对BlockingQueue这个后续会在执行器里使用的基本数据结构做源码分析,为后续的Executor源码分析做准备。我们先来看Doug Lea的定义,BlockingQueue是一个队列,该队列支持两种特...

后厂村老司机 267

LPDDR4协议规范之 (四)命令和时序

LPDDR4协议规范之 (四)命令和时序命令真值表激活操作读写访问操作读前沿和后沿突发读取操作流程读操作时序写前沿和后沿突发写操作写入均衡(待更新) 命令真值表 激活操作 ACTIVATE命令由两个连续命令组成,Activate-1命令和Activate-2。通过在(Activate-1)时钟的第一个上升沿保持CS HIGH,CA0 HIGH和CA1 LOW来发出Activate-1命令,通过...

YJFeiii的博客 2万+

基于51单片机扫地机器人(全套Proteus仿真+原理图+程序+说明书)

(内含源程序代码,原理图,仿真,讲解视频,元件清单等,【精品】值得推荐!!!扫地机器人是以单片机为主控制器。通过单片机控制小车行驶、除尘、蜂鸣。扫地机器人使用双电机驱动,以提高整车运动的平稳性;在智能车进驶过程中,采用双超声波模块实现避障。

2301_76434107的博客 1897

java集合类深入分析之PriorityQueue

PriorityQueue介绍     在平时的编程工作中似乎很少碰到PriorityQueue(优先队列) ,故很多人一开始看到优先队列的时候还会有点迷惑。优先队列本质上就是一个最小堆。前面一篇文章介绍了堆排序和堆的性质。而堆又是什么呢?它是一个数组,不过满足一个特殊的性质。我们以一种完全二叉树的视角去看这个数组,并用二叉树的上下级关系来映射到数组上面。如果是最大堆,则二叉树的顶点是保存的...

点缀星辰 755

小米路由器R1D进阶玩法:MIXBOX工具箱安装与插件管理指南

本文详细介绍了为小米路由器R1D安装MIXBOX工具箱的完整指南。通过开启SSH、执行一键安装脚本,用户可以轻松解锁路由器的进阶功能,如安装离线下载、内网穿透等插件,从而将旧设备转变为强大的家庭网络服务中心。

weixin_29292431的博客 1118

Java集合框架之七-------------PriorityQueue源码解析

1.总体介绍 PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。优先队列,能保证每次取出的元素都是队列中权值最小的。元素大小的评判可以采用自然排序也可以通过传入的comparator比较器进行排序。 Java中的PriorityQueue实现了Queue接口,不允许放入null元素,其通过堆实现,具体说是通过完全二叉树实现的小顶堆(任意一个非叶子节点的权值都不大于其左右节...

huangwei18351的博客 902

谈谈人大金仓数据库

人大金仓数据库(Kingbase)是国产自主研发的关系型数据库管理系统,兼容主流数据库语法,支持高并发、高安全性及国产化适配。该数据库提供完整的安装部署方案,包括环境准备、初始化配置和验证流程,并配备专业的数据迁移工具(KDMS)实现从Oracle/MySQL等数据库的平滑迁移。系统提供KStudio等图形化管理工具,支持性能监控、备份恢复等运维功能,同时具备性能调优、高可用架构、分区表管理等高级特性,满足政府、金融等领域的企业级需求。

蜚鸣的博客 2107

保姆级避坑指南:用Livox官方工具搞定Mid-360多雷达自动标定(附源码Bug修复)

本文详细解析了使用Livox官方工具进行Mid-360多雷达自动标定的全流程,包括环境搭建、工具链配置、关键Bug修复及数据采集最佳实践。重点解决了PointCloudMapper.cpp边界检查缺失和calibration.cpp点云显示问题,提供了实用的代码修复方案和标定质量评估指标,帮助开发者高效完成激光雷达标定任务。

weixin_29053695的博客 281

大顶堆小顶堆优先队列

特性和应用场景 大顶堆小顶堆,也叫优先队列,是一种基于数组+平衡二叉树的数据结构。 主要用于排序,增减操作的速度较快(O(logn)) 适合带有优先级的排序场景,比如处理订单的时候,VIP用户的优先级更高,当前队列有人排队可以进行插队。 基本结构 下面就是大顶堆的图示,这两个都是正确的大顶堆。 注意堆的每一个元素有一个从上到下的序号,序号代表数组(堆的成员变量)的索引。 JAVA中的堆是 优先队列,就是 PriorityQueue,下面是其简单介绍。 /** * An unbounded priori

weixin_43680337的博客 1528

BGP路由聚合:自动聚合和手动聚合

路由聚合是指将多条具体的路由合并为一条聚合路由,以减少路由表的条目数。这种技术通过只向对等体发送聚合后的路由,而不发送所有的具体路由,来减小路由表的规模。同时,被聚合的路由如果发生路由振荡,也不再对网络造成影响,从而提高了网络的稳定性。

网络技术联盟站 1222

JDK源码之PriorityQueue源码剖析

转载至:https://www.cnblogs.com/showing/p/6759341.html 一.优先队列的应用 优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后,首先将它放到队列的最后,而操作系统内部的Scheduler负责不断地从这个优先队列中取出优先级较高的进程执行;爬虫系统在执行时往往也需要从...

qq_39110789的博客 173

GPFS扩展技术原理(十一)-FMDN广播与EID加解密

GFPS扩展技术原理(十一)FMDN广播及EID加解密

十多年蓝牙协议软件开发,擅长蓝牙协议分析 936

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jdk源码分析PriorityQueue

一、结构 PriorityQueue是一个堆,任意节点都是以它为根节点的子树中的最小节点 堆的逻辑结构是完全二叉树状的,存储结构是用数组去存储的,随机访问性好。最小堆的根元素是最小的,最大堆的根元素是最大的 这是一个最小堆的逻辑结构 这是他的存储结构,是用数组来存储的。 可以看到,i下标的数组元素,他的父节点是(i-1)/2,他的左右节点分别是i*2+1,i*2+2 二、容量 ...

weixin_34018202的博客 86

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

java实现优先队列_详解优先队列在JDK中的实现方式

这篇文章主要为大家详细介绍了JDK源码之PriorityQueue,具有一定的参考价值,感兴趣的小伙伴们可以参考一下一.优先队列的应用优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后,首先将它放到队列的最后,而操作系统内部的Scheduler负责不断地从这个优先队列中取出优先级较高的进程执行;爬虫系统在执行时往往也需要从一个...

weixin_34637138的博客 493

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

《Java源码分析》:BlockingQueue之PriorityQueue

PriorityQueue类相关属性介绍1、默认容量2、最大容量3、二叉堆//基于二叉堆来实现优先队列,queue[i]的子节点为queue[2*i+1]/queue[2*i+2];4、优先队列元素个数5、比较器,优先队列中的元素就是按照此比较器进行排序。PriorityQueue类相关构造函数介绍1)、创建一个优先队列对象,默认大小为11,队列中的元素按照自然顺序排序。2)、创建一个指定大小的优先队列对象,队列中的元素按照自然顺序排序。

smart_an的专栏 931

Java并发编程与堆算法面试突破指南

并发编程是Java开发中的核心难点,其本质是解决共享资源访问的三大特性:可见性、原子性和有序性。通过volatile、synchronized和CAS等机制,可以确保多线程环境下的数据一致性。JUC工具类如ConcurrentHashMap和AQS,为高并发场景提供了高效解决方案。堆作为一种完全二叉树结构,在解决TopK问题、任务调度等场景中表现出色。结合JUC原理与堆算法实践,不仅能深入理解并发控制机制,还能提升算法解题能力。本文通过JUC知识体系拆解和堆算法精讲,帮助开发者构建系统的面试准备策略,涵盖从

weixin_33827731的博客 504

Re:从零开始的DS生活 轻松从0基础实现多种队列

本文详细介绍了队列的概念和性质,简要的介绍了队列ADT并附三种实现方式(链式、顺序api、顺序+动态扩容),对循环、双端、阻塞、优先级队列进行简单的应用与jdk源码分析,供读者理解与学习,适合点赞+收藏。有什么错误希望大家直接指出~

小明的Java问道之路 1万+

数据结构核心术语与实战应用全解析

数据结构是计算机科学的基础,它定义了数据的组织、存储和管理方式。从线性结构的数组、链表,到非线性结构的树、图,每种数据结构都有其独特的原理和应用场景。数组适合快速随机访问,链表则擅长频繁插入删除;栈和队列分别遵循LIFO和FIFO原则,在算法设计中扮演重要角色。哈希表通过散列函数实现O(1)查询,而二叉搜索树则提供有序数据的高效检索。在实际工程中,合理选择数据结构能显著提升系统性能,如使用B+树优化数据库索引,或利用跳表实现高效的有序集合。掌握这些核心概念,不仅能应对技术面试中的高频考题,更能为开发高性能应

weixin_33895475的博客 395

python删除列表中元素_python如何删除列表一个元素

下面举例说明几种python删除列表中元素的方法方法一用remove("")方法删除指定元素,没有该元素时报错>>> number=[1,3,2,0]>>> number.remove(1)#删除指定元素1,这里是int类型因此不需要引号>>> print(number)[3, 2, 0]方法二利用del[索引数] 函数删除指定索引数的元素>>> number=[1,3,2,0]>>> del n...

weixin_39895481的博客 624

java并发编程之美-阅读记录7

java并发包中的并发队列 7.1ConcurrentLinkedQueue   线程安全的无界非阻塞队列(非阻塞队列使用CAS非阻塞算法实现),其底层数组使用单向列表实现,对于出队和入队操作使用CAS非阻塞来实现线程安全的。   1、结构:      ConcurrentLinkedQueue内部的对列使用的是单向链表实现,并且有两个用volatile修改的节点头结点head...

weixin_30587025的博客 208

最小堆建立java_【java】最大堆和最小堆的建立

最大堆public class MaxHeap {private static int size = 0;private void maxHeap(int k, Integer key, Integer[] array){while (k > 0){//父节点,即array的中点int parent = (k - 1) >>> 1;Integer e= array[pare...

weixin_30828697的博客 475
上一篇: 基于zookeeper的分布式lock实现
下一篇: 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
hxpjava1
博客等级 码龄19年 1365粉丝 511原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值