当前位置: 首页 > news >正文

堆(Java实现)

一:堆(PriorityQueue)

1:堆的概念:

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

2:堆的性质

1:堆中某个节点的值总是不大于或不小于其父节点的值;2:堆总是一棵完全二叉树

1:小根堆:

根的值总是小于左子树和右子树,存储结果是采用层序遍历的结果。

2:大根堆

根的值总是大于左子树和右子树,存储结构是采用层序遍历的结果。

3:堆的存储方式

从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储,

注意:对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低。

将元素存储到数组中后,可以根据二叉树章节的性质对树进行还原。假设i为节点在数组中的下标,则有:
1:如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
2:如果2 * i + 1 小于节点个数,则节点i的
左孩子下标为2 * i + 1,否则没有左孩子(左孩子表示方式是:2 * i + 1
3:如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子(右孩子表示方式是:2 * i + 2

4:堆的创建

4.1:采用向下调整的方式创建堆

4.1.1:大根堆(小根堆只需要将下述的if语句代码改为<即可):

初始化数组:

对要排序的数组进行初始化,用userSize代表数组元素的个数,elem数组存储传入的数组元素。

4.1.2:向下调整(shifDown):

从最后一颗子树开始调整为大根堆,假设最后一棵树的根节点为parent,然后从parent所在的子树开始逐一调整,没调整一颗树parent就parent--,parent然后跳转到倒数第二课树,然后再将此树调整为大根堆。parent=(userSize-1-1)/2

注意:已知孩子节点下标为i 则双亲节点的值是多少?(i-1)/2
已知父亲节点下标为i
左孩子:2*i+1;右孩子:2*i+2

那么,siftDown方法如何编写呢,siftDown方法实现的是根节点与子节点的最大时比较,然后parent与子节点中的最大值交换位置,这样就实现了子树的大根堆。

swap方法是任意两个传过来的节点都可以交换位置,不只parent节点和child节点:


整个过程:

shifDown时间复杂度分析:

从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为logN

4.1.3:建根的时间复杂度

向上调整(shifUp):

向上调整是接收一个孩子节点的参数的位置,然后确定这个孩子节点的根节点parent,然后逐一遍历调整。

5:堆的插入(offer):

首先判断是否数组已满,已满扩容,然后在堆的末尾节点添加要插入val值,采用shifUp的形式对堆进行排序。
也可以直接用offer插入方法直接建大根堆,数组一开始为空,一个一个插入,然后一个一个调整。

6.堆的删除(delete)

注意:堆的删除一定删除的是堆顶元素。具体如下:
1:将堆顶元素对堆中最后一个元素交换
2:将堆中有效数据个数减少一个
3:对堆顶元素进行向下调整

二 : 用接口介绍:

 PriorityQueue的特性:

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,主要介PriorityQueue。

三:top-k问题:最大或者最小的前k个数据。

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

求前k个最小的

1:整体排序

2:建立大小为k的小根堆

3:把前k个元素创建为大根堆,遍历剩下的N-k个元素,和堆顶比较,如果比堆顶小,则把堆顶删除,当前元素插入

第二种方法实现:

直接建立小根堆,然后poll出前k个即可。

第三种方法的实现:

四:堆的应用

4.1 PriorityQueue的实现

用堆作为底层结构封装优先级队列

4.2 堆排序

堆排序即利用堆的思想来进行排序,总共分为两个步骤

1:建堆
升序:   建大堆
降序:   建小堆
2:利用堆删除思想来进行排序

建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序

http://www.dtcms.com/a/325126.html

相关文章:

  • 大数据架构演变之路
  • [激光原理与应用-222]:机械 - 3D设计与2D设计的异同比较
  • 赋值运算符指南
  • GoBy 工具安装 | Windows 操作系统安装 GoBy
  • 某市智慧社区企业管理平台原型设计:数据驱动的社区治理新路径
  • 常用hook钩子函数
  • 设备活动审计技术方案解析
  • WSL创建虚拟机配置VNC
  • Linux系统编程——进程控制
  • 编程基础之多维数组——计算鞍点
  • 六、RuoYi-Cloud-Plus OSS文件上传配置
  • [Python 基础课程]常用函数
  • 数学与应用数学专业大学如何规划?就业前景怎么样?
  • vue3中 getCurrentInstance
  • 疯狂星期四文案网第35天运营日记
  • 补卡day16
  • special topic 8 (2) and topic 9 (1)
  • 亚麻云之全球加速器——CloudFront(CDN)服务入门
  • 系统测试讲解 - Java使用selenium实现滑块验证的处理详解
  • 关于linux操作系统下的文件操作方法:
  • 深度解析1688关键字搜索API接口:技术实现与应用探索
  • 【Nginx知识】nginx日志配置详解
  • 使用线性降维方法进行数据降维
  • token危机解决?扩散模型数据潜力3倍于自回归,重训480次性能仍攀升
  • Java历代JDK核心特性演进(JDK9-21精华版)
  • 【Docker实战入门】从核心概念到镜像构建
  • 微服务架构中过滤器(Filter)与拦截器(Interceptor)的区别
  • 线程池111
  • Spring Boot - 内置的9个过滤器用法
  • 串联所有单词的子串