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

数据结构与算法——Java实现 32.堆

目录

大顶堆

威廉姆斯建堆算法

Floyd建堆算法

Floyd建堆算法复杂度

大顶堆代码实现


人的想法和感受是会随着时间的认知改变而改变,

原来你笃定不会变的事,也会在最后一刻变得释然

                                                                —— 24.10.10

堆是基于二叉树实现的数据结构

大顶堆任意一个父节点的权值要大于两个孩子的权值,同一层节点的权值大小无关

小顶堆任意一个父节点的权值要小于两个孩子的权值,同一层节点的权值大小无关


大顶堆

威廉姆斯建堆算法

不断的向堆中添加节点,添加时与堆最末尾元素进行比较,如果权值大于最末尾元素,则不断上调与其(最末尾元素,不断更新)父元素比较,直到找到小于堆中某元素的值或更新到堆顶元素

时间复杂度为O(n*logn)


Floyd建堆算法

1.找到最后一个非叶子节点 索引【size / 2 - 1】

2.从后向前,对每个结点执行下潜(与其左右孩子节点中的较大值进行交换)

Floyd建堆算法复杂度

复杂度与堆的高度h有关,高度从下往上由1开始依次相加,交换次数为h-1,总交换次数为每个节点的总高度除以结点所在每一层的高度 *(高度-1)之和

i指的是结点的高度

h指的是堆的总高度

推导出

        O(n) = 2^h-h-1

        ∵ 2^h ≈ n,h ≈ log2n

因此Floyd建堆算法的时间复杂度为O(n)


大顶堆代码实现

一、建堆方法(buildHeap

该方法通过从最后一个非叶子节点开始,逐个节点进行下潜操作,确保堆的性质。循环从size / 2 - 1开始是正确的,因为这是最后一个非叶子节点的索引。对于每个节点,调用down方法进行下潜操作,以确保节点的值不小于其子节点的值。

二、下潜方法(heapifyDown

  1. 正确地计算了当前节点的左子节点索引left = parent * 2 + 1和右子节点索引right = left + 1
  2. 找到当前节点及其两个子节点中的最大值索引(max),并与当前节点索引(parent)进行比较。如果找到了更大的子节点,则进行交换,并递归地对新的位置进行下潜操作。

三、交换方法(swap

该方法简单地交换两个索引处的元素值

四、获取堆顶元素方法(peek

如果堆为空(size == 0),返回 -1,否则返回堆顶元素(array[0]

五、删除堆顶元素方法(poll

  1. 如果堆为空,返回 -1。
  2. 保存堆顶元素,将堆顶元素与最后一个元素交换,然后减小堆的大小。
  3. 对新的堆顶元素进行下潜操作,以维持堆的性质。

六、删除指定索引处的元素方法(poll(int index)

  1. 如果堆为空,返回 -1。
  2. 保存指定索引处的元素,将其与最后一个元素交换,然后减小堆的大小。
  3. 对交换后的元素从指定索引处进行下潜操作,以维持堆的性质。

七、替换堆顶元素方法(replace

将新元素赋值给堆顶元素,然后对堆顶元素进行下潜操作,以维持堆的性质。

八、添加元素方法(offer

  1. 如果堆已满,返回 false。
  2. 将新元素添加到堆的末尾,然后调用up方法对新元素进行上浮操作,以维持堆的性质。最后增加堆的大小。

九、上浮方法(heapifyUp

从新添加元素的索引位置开始,向上比较新元素与父节点的值。如果新元素大于父节点,则交换它们,并继续向上比较,直到新元素小于父节点或者到达堆顶。

import java.util.Arrays;public class MaxHeap {int[] heapArray;int size;public MaxHeap(int capacity) {heapArray = new int[capacity];}public MaxHeap(int[] initialArray) {heapArray = new int[initialArray.length];System.arraycopy(initialArray, 0, heapArray, 0, initialArray.length);size = initialArray.length;buildHeap();}private void buildHeap() {for (int i = size / 2 - 1; i >= 0; i--) {heapifyDown(i);}}private void heapifyDown(int index) {int leftChildIndex = 2 * index + 1;int rightChildIndex = 2 * index + 2;int largestIndex = index;if (leftChildIndex < size && heapArray[leftChildIndex] > heapArray[largestIndex]) {largestIndex = leftChildIndex;}if (rightChildIndex < size && heapArray[rightChildIndex] > heapArray[largestIndex]) {largestIndex = rightChildIndex;}if (largestIndex!= index) {swap(index, largestIndex);heapifyDown(largestIndex);}}private void swap(int i, int j) {int temp = heapArray[i];heapArray[i] = heapArray[j];heapArray[j] = temp;}public int peek() {if (size == 0) {return -1;}return heapArray[0];}public int poll() {if (size == 0) {return -1;}int maxValue = heapArray[0];heapArray[0] = heapArray[size - 1];size--;heapifyDown(0);return maxValue;}public int poll(int index) {if (size == 0 || index >= size) {return -1;}int removedValue = heapArray[index];heapArray[index] = heapArray[size - 1];size--;heapifyDown(index);return removedValue;}public void replace(int newValue) {if (size == 0) {return;}heapArray[0] = newValue;heapifyDown(0);}public boolean offer(int value) {if (size == heapArray.length) {return false;}heapArray[size] = value;heapifyUp(size);size++;return true;}private void heapifyUp(int index) {int parentIndex = (index - 1) / 2;while (index > 0 && heapArray[index] > heapArray[parentIndex]) {swap(index, parentIndex);index = parentIndex;parentIndex = (index - 1) / 2;}}public static void main(String[] args) {int[] initialArray = {1, 2, 3, 4, 5, 6, 7};MaxHeap maxHeap = new MaxHeap(initialArray);System.out.println(Arrays.toString(maxHeap.heapArray));// [7, 5, 6, 4, 2, 1, 3]maxHeap.replace(5);System.out.println(Arrays.toString(maxHeap.heapArray));// [6, 5, 5, 4, 2, 1, 3]maxHeap.poll(2);System.out.println(Arrays.toString(maxHeap.heapArray));// [6, 5, 3, 4, 2, 1, 3]System.out.println(maxHeap.peek());// 6maxHeap.poll();System.out.println(Arrays.toString(maxHeap.heapArray));// [5, 4, 3, 1, 2, 1, 3]System.out.println(maxHeap.offer(5));// trueSystem.out.println(Arrays.toString(maxHeap.heapArray));// [5, 4, 5, 1, 2, 3, 3]maxHeap.poll();System.out.println(Arrays.toString(maxHeap.heapArray));// [5, 4, 3, 1, 2, 3, 3]maxHeap.offer(9);System.out.println(Arrays.toString(maxHeap.heapArray));// [9, 4, 5, 1, 2, 3, 3]}
}

相关文章:

数据结构与算法——Java实现 32.堆

目录 堆 大顶堆 威廉姆斯建堆算法 Floyd建堆算法 Floyd建堆算法复杂度 大顶堆代码实现 人的想法和感受是会随着时间的认知改变而改变&#xff0c; 原来你笃定不会变的事&#xff0c;也会在最后一刻变得释然 —— 24.10.10 堆 堆是基于二叉树实现的数据结构 大顶堆任意一个父节…...

深度学习 .dot()

在 MXNet 中&#xff0c;.dot() 是用于计算两个数组的点积&#xff08;矩阵乘法&#xff09;的方法。这个方法适用于一维和二维数组&#xff0c;并返回它们的点积结果。 语法 ndarray1.dot(ndarray2) 参数 ndarray1: 第一个输入数组。ndarray2: 第二个输入数组&#xff0c;…...

idea2024 git merge 时丢失 Merge remote-tracking branch问题

idea2024 git merge 时丢失 Merge remote-tracking branch问题 处理建议 直接修改本地git的配置 git config --global merge.ff false 分析 在 IntelliJ IDEA 中进行 Git merge 操作时&#xff0c;有时你可能会遇到提交历史中丢失 Merge remote-tracking branch 的信息&#…...

pdf怎么删除多余不想要的页面?删除pdf多余页面的多个方法

pdf怎么删除多余不想要的页面&#xff1f;在日常办公或学习中&#xff0c;我们经常会遇到需要处理PDF文件的情况。PDF文件因其格式稳定、不易被篡改的特点而广受青睐&#xff0c;但在编辑方面却相对不如Word等文档灵活。有时&#xff0c;在接收或创建的PDF文件中&#xff0c;可…...

树莓派应用--AI项目实战篇来啦-3.OpenCV 读取写入和显示图像

1. 介绍 在计算机视觉和图像处理领域&#xff0c;读取和显示图像是最基础且常见的操作之一&#xff0c;OpenCV作为一个强大的计算机视觉库&#xff0c;提供了丰富的功能来处理图像数据。 读取、显示和写入图像是图像处理和计算机视觉的基础&#xff0c;即使裁剪、调整大…...

一句话就把HTTPS工作原理讲明白了

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 上午好&#xff0c;我的网工朋友。 在当今互联网高度发达的时代&#xff0c;信息安全已成为不容忽视的重要议题。 随着越来越多的个人信息和敏感…...

CPU 和处理核心(Core)中间有3个缓存

一、CPU 和处理核心&#xff08;Core&#xff09;的关系 CPU和处理核心之间的关系是整体与部分的关系。随着多核技术的发展&#xff0c;现代CPU通过包含多个处理核心来提高其并行处理能力和整体性能&#xff0c;同时在核心之间实现资源的有效共享和独立使用。这种架构的进步使…...

前后分离项目记录

一.前端设置 1.打包问题 打包报错 Thread Loader时&#xff0c;增加以下代码&#xff1a; 2.上线时api设置 二.Nginx问题 1.缓存问题&#xff1a;添加如下代码以禁止缓存&#xff0c;否则在关闭nginx后仍然可以访问页面 2.跨域问题在后端加CrossOrigin注解即可 3.上线时co…...

一句话木马的多种变形方式

今天来和大家聊一聊&#xff0c;一句话木马的多种变形方式。 经常有客户的网站碰到被上传小马和大马&#xff0c;这里的“马”是木马的意思&#xff0c;可不是真实的马。 通常&#xff0c;攻击者利用文件上传漏洞&#xff0c;上传一个可执行并且能被解析的脚本文件&#xff0c;…...

【NestJS入门到精通】装饰器

目录 方法装饰器通过prototype添加属性、方法 属性装饰器拓展 方法装饰器参数装饰器 方法装饰器 ClassDecorator 定义了一个类装饰器 a&#xff0c;并将其应用于类 A。装饰器 a 会在类 A 被定义时执行。 const a:ClassDecorator (target:any)>{console.log(target,targe…...

XML 编辑最简单好用的 QXmlEdit 软件已经完整中文化

XML 编辑最简单好用的 QXmlEdit 软件已经完整中文化 简介一、软件界面二、安装下载2.1 QXmlEdit 官方网站下载2.2 QXmlEdit 源代码下载2.3 QXmlEdit 软件中文版下载 三、QXmlEdit 编辑 ADCP 测量项目的 MMT 文件3.1 应用 XML 文件缩进3.2 使用 QXmlEdit 缩进编辑保存后&#xf…...

ref标签、style的scope

ref标签 作用&#xff1a;用于注册模板引用。 用在普通DOM标签上&#xff0c;获取的是DOM节点。用在组件标签上&#xff0c;获取的是组件实例对象。 DOM&#xff1a; <template><div class"person"><h2 ref"title2">上海</h2>&l…...

22年408数据结构

第一题&#xff1a; 解析&#xff1a; 观察一下这个程序&#xff1a;我们注意到最外层的循环是从i1开始的&#xff0c;每次ii*2&#xff0c;直到i<n为止&#xff0c;假设程序总共执行k次执行&#xff0c;则有2^(k1)>n。则k1>log(2)n这里是以2为底n的对数, k>log(2)…...

ubuntu 虚拟机将linux文件夹映射为windows网络位置

在使用虚拟机时可以选择将windows的文件夹设置为共享文件夹方便在虚拟机中访问windows中的文件,同理,也可以将linux的文件夹共享为一个网络文件夹,通过windows的添加一个网络位置功能,将linux的文件夹映射到windows本地,方便windows访问使用linux的文件夹 参照如下:https://blo…...

Pytho逻辑回归算法:面向对象的实现与案例详解

这里写目录标题 Python逻辑回归算法&#xff1a;面向对象的实现与案例详解引言一、逻辑回归算法简介1.1 损失函数1.2 梯度下降 二、面向对象的逻辑回归实现2.1 类的设计2.2 Python代码实现2.3 代码详解 三、逻辑回归案例分析3.1 案例一&#xff1a;简单二分类问题问题描述数据代…...

AWS WAF实战指南:从入门到精通

1. 引言 Amazon Web Services (AWS) Web Application Firewall (WAF) 是一款强大的网络安全工具,用于保护Web应用程序免受常见的Web漏洞攻击。本文将带您从入门到精通,深入探讨AWS WAF的实际应用策略,并提供具体案例,帮助您更好地保护您的Web应用程序。 2. AWS WAF基础 …...

k8s的部署

一、K8S简介 Kubernetes中文官网&#xff1a;Kubernetes GitHub&#xff1a;github.com/kubernetes/kubernetes Kubernetes简称为K8s&#xff0c;是用于自动部署、扩缩和管理容器化应用程序的开源系统&#xff0c;起源于Google 集群管理工具Borg。 Kubernetes集群组件逻辑图…...

C# 两个进程/exe通讯方式 两个应用程序通讯方式

C# 两个exe通讯方式 两个应用程序通讯方式 1. 命名管道&#xff08;Named Pipes&#xff09; 1.1. 概述 命名管道是一种用于在同一台机器或网络中不同进程之间进行双向通信的机制。它支持同步和异步通信&#xff0c;适用于需要高效数据传输的场景。 1.2. 特点 双向通信&am…...

ubuntu下打开摄像头

ubuntu下打开摄像头 在Ubuntu下,你可以使用cheese,这是一个开源的摄像头应用程序。如果你还没有安装它,可以通过以下命令安装: sudo apt-get updatesudo apt-get install cheese 安装完成后,你可以通过命令行启动它: cheese 或者,你也可以使用ffmpeg来打开摄像头并进…...

ABAP 表转JSON格式

FUNCTION ZRFC_FI_SEND_PAYPLAN2BPM. *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *" IMPORTING *" VALUE(INPUT) TYPE ZSRFC_FI_SEND_PAYBPM_IN *" EXPORTING *" VAL…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...