当前位置: 首页 > 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…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...