当前位置:首页 » 编程语言 » java二叉堆

java二叉堆

发布时间: 2025-05-25 15:24:59

1. 【JDK源码分析】Timer/TimerTask 源码分析

java中,Timer 类是实现定时任务的常见工具,配合TimerTask 实现定时、延迟或周期性执行。本文将深入剖析其源码结构和工作原理。


Timer 的核心机制涉及关键类,包括TimerThread、Timer、TimerQueue 和 TimerTask。一个Timer 实例对应一个TimerThread,负责执行任务;Timer拥有一个TimerThread和一个TimerQueue,而TimerQueue中存储了多个TimerTask。这样的关系可以总结为:



  • 1个 TimerThread -> 1个线程

  • 1个 Timer -> 持有 TimerThread 和 TimerQueue

  • 1个 TimerQueue -> 持有多个 TimerTask


源码分析时,首先创建Timer时,thread和queue会在声明时初始化为final类型,确保它们与Timer的生命周期绑定。接着,任务通过schele方法进行调度,这个过程会根据TimerTask类型设置不同的period参数。


TimerTask 是一个实现了Runnable接口的抽象类,子类需实现run方法。TimerTask的类型决定了其执行周期。TimerThread的run方法包含一个死循环,类似Android的Handler机制。


TimerQueue作为队列,内部使用完全二叉树结构,add和fixUp方法用于维护最小执行时间的节点在队列前端。purge方法执行后,会调用fixDown方法进行调整。


总之,每个Timer实例由一个线程和一个二叉堆(通过TimerQueue实现)组成,用于管理定时任务的执行顺序。理解这些核心组件的交互,有助于深入理解Timer的工作机制。

2. 看图说话之二叉堆(优先队列)——原理解析

    优先队列更多的是一种逻辑上和业务上的设计。队列中的每项元素都分配一个优先权值,队列的出队顺序按照优先权值来划分,高优先权先出队或者低优先权先出队。这样一个优先队列必须具备两个最基本的操作——入队,以及高(低)优先权出队。优先队列在很多场景中都有运用,比如打印机的任燃答段务调度和操作系统中的进程调度都有用到优先队列的设计。

    此时我们假设并不知道有堆这样的数据结构,想实现上述这样的功能,其实也可以有多种解决方案,比如以下两种:

    二叉堆如其名字一样和二叉树具有紧密的关系。二叉堆是一种特殊的二叉树,是对一般的二叉树提出了结构性和堆序性的要求,这种特殊结构性和堆序性是二叉堆的性质所在。

1.结构性:二叉堆是一个完全二叉树

2.堆序性:所有的节点值均小于(大于)其后裔节点值,若所有节点值大于其后裔节点这样的二叉堆称为大根堆##点值均小于其后裔节点这样的二叉堆成为小根堆。

    这里可以看到,假如是小根堆的情况,那么每次取堆顶的元素,就完成了按低优先级出队的功能。若是大根队取堆顶的元素则完成按高优举嫌先级出对的顺序。
    这里需要特别注意就是,每次的出队操作=返回堆顶元素+删除堆顶元素,每次删除堆顶元素之后,需要保证依旧满足二叉堆的结构性和对堆序性,这个删除和调整的过程称为堆调整。
    下面以大根堆为例进行介绍一次堆调整,并且分析其时间复杂度为什么是O(logN)。下文描述中,堆的删除操作=优先队列的出队,堆的插入操作=优先队列的入队。

    上文介绍了大根堆的出队操作,其时间复杂度在O(logN),此处介绍大根堆的入队操作,入队操作和出队操作和其相似,最坏时间复杂度也是O(logN)。下面将通过图例的形式分析大根堆的入队操作,假设插入元素是19。

2.如图9所示,皮誉在插入元素之后二叉堆的结构特性已经满足了,下面主要需要调整堆序特性。对于元素19而言,找到其父亲元素8,判断堆序性,发现19大于8,所以交换19和8的位置,结果如下。

Reference:
[1] 数据结构与算法 java语言描述版
[2] 博客原文

3. Java中堆和栈创建对象的区别

堆和栈是信息学数据结构通用名词,不仅在Java中,C++里也有调用模板。
堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全树。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。
堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。
(ki
<=
k2i,ki
<=
k2i+1)或者(ki
>=
k2i,ki
>=
k2i+1),
(i
=
1,2,3,4...n/2)
若将和此次序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

4. java中都有哪些数据结构

数据结构:
①数组 (Array)
在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数
据元素的集合称为数组。在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组
元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指
针数组、结构数组等各种类别。
②栈 (Stack)
栈是只能在某一端插入和删除的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后
的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
③队列 (Queue)
一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行
插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
④链表 (Linked List)
一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:
一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
⑤树 (Tree)
树是包含n(n>0)个结点的有穷集合K,且在K中定义了一个关系N,N满足 以下条件:
(1)有且仅有一个结点 k0,他对于关系N来说没有前驱,称K0为树的根结点。简称为根(root)
(2)除K0外,k中的每个结点,对于关系N来说有且仅有一个前驱。
(3)K中各结点,对关系N来说可以有m个后继(m>=0)。
⑥堆 (Heap)
在计算机科学中,堆是一种特殊的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指
二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。
⑦图 (Graph)
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,
边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
⑧散列表 (Hash)
若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上。由此,不需比较便可直接取得所查记录。称
这个对应关系f为散列函数(Hash function),按这个思想建立的表为散列表。
差不多我就知道这些了~

5. java在存储数组时栈内存和堆内存的联系是什么

堆和栈都是一种数据项按序排列的数据结构。

(1)栈就像装数据的桶或箱子:它是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。这就如同要取出放在箱子里面底下的东西(放入的比较早的物体),首先要移开压在它上面的物体(放入的比较晚的物体)。

(2)堆像一棵倒过来的树:堆是一种经过排序的树形数据结构,每个结点都有一个值。通常所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且慎败饥根结点的宽返两个子树也是一个堆。由于堆的这个特性,常用来实现优先队列,堆的存取是随意,这就如同在图书馆的书架上取书,虽然书的摆放是有顺序的,但是想取任意一本时不必像栈一样,先取出前面所有的书,书架这枯运种机制不同于箱子,可以直接取出想要的书。

热点内容
忘记密码如何改指纹 发布:2025-05-25 20:55:09 浏览:613
5位密码挂锁如何设置新密码 发布:2025-05-25 20:51:25 浏览:124
jad反编译乱码 发布:2025-05-25 20:43:29 浏览:31
岛风go本地缓存 发布:2025-05-25 20:43:18 浏览:176
移动广告系统源码 发布:2025-05-25 20:42:38 浏览:386
linux系统grub 发布:2025-05-25 20:21:44 浏览:244
c语言reg 发布:2025-05-25 20:19:29 浏览:806
编程大佬qq 发布:2025-05-25 20:18:54 浏览:650
怎样获得dsg服务器地址 发布:2025-05-25 20:15:10 浏览:777
房贷算法变了 发布:2025-05-25 20:12:17 浏览:262