数据结构-堆

一、什么是堆

先了解两种特别的二叉树

满二叉树

除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树

完全二叉树

完全二叉树相对于满二叉树来说,最后一层叶子节点从左到右中间没有空缺的,像这样:

计算机科学中,堆是一种基于树的数据结构,通常用完全二叉树实现。堆的特性如下

  • 大顶堆中,任意节点 C 与它的父节点 P 符合 p.value >= c.value
  • 小顶堆中,任意节点 C 与它的父节点 P 符合 p.value <= c.value
  • 最顶层的节点(没有父亲)称之为 root 根节点

完全二叉树可以使用数组来表示,像下图这样

如果从索引 0 开始存储节点数据,它的特征如下:

  • 节点i的父节点为 floor((i-1)/2)
  • 当 i>0 时,节点i的左子节点为2i+1,右子节点为2i+2,当然它们得小于size

二、堆插入元素

以小堆为例,在插入元素的时候,先把元素放到数组的最后,然后与父节点比较,如果比父节点大,就插入成功了,如果比父节点小就跟父节点交换位置,直到它比父节点大或到达跟节点为止。

下面是代码实现

    /**** @param e 添加的元素* @return 是否成功*/public boolean offer (Integer e) {int i = size;size = i + 1;if (i == 0) {queue[i] = e;} else {siftUp(i, e);}return true;}/*** 1. 获取父节点* 2. 让元素与父节点比较,如果小于就交换位置,大于就结束* @param i 被添加元素的索引* @param e 被添加元素的值*/public void siftUp(int i, Integer e) {queue[i] = e;while (i > 0) {int parent = (i - 1) / 2;if (e > queue[parent]) {break;}swap(i, parent);i = parent;}}

三、出堆实现

  1. 弹出数组第一个元素返回
  2. 把数组最后一个元素放到第一位,然后对它元素进行下潜操作,下潜操作分为这3个步骤
  • 计算左子结点和右子节点
  • 左子节点和右子节点中较小的一个和父节点比较(子节点的index不能大于size)
  • 如果有比父节点小的就交换位置,直到到达叶子节点或者左子节点或右子节点没有小于父节点的就结束

代码实现:

    /***  1.返回第一个元素*  2.第一个元素与最后一个元素交换*  3.size--,最后一个元素置为null*  4.对第一个元素执行下潜操作*/public Integer poll() {if (size == 0) {throw new RuntimeException("Null");}Integer result = queue[0];swap(0, size - 1);queue[--size] = null;siftDown(0);return result;}/*** 1. 计算左子结点和右子节点* 2. 左子节点和右子节点中较小的一个和父节点比较(子节点的index不能大于size)* 3. 如果有比父节点小的就交换位置,直到到达叶子节点或者左子节点或右子节点没有小于父节点的就结束* @param index 要下潜元素的索引*/public void siftDown(int index) {int parent = index;int left = index * 2 + 1;int right = left + 1;if (left < size && queue[left] < queue[parent]) {parent = left;}if (right < size && queue[right] < queue[parent]) {parent = right;}// 说明找到更小的了if (parent != index) {swap(parent, index);siftDown(parent);}}

四、完整代码

public class Heap {private static final int DEFAULT_INITIAL_CAPACITY = 11;transient Integer[] queue;private int size = 0;public Heap() {queue = new Integer[DEFAULT_INITIAL_CAPACITY];}public static void main(String[] args) {Heap heap = new Heap();heap.offer(1);heap.offer(5);heap.offer(2);heap.offer(4);heap.offer(3);heap.poll();heap.poll();}/**** @param e 添加的元素* @return 是否成功*/public boolean offer (Integer e) {int i = size;size = i + 1;if (i == 0) {queue[i] = e;} else {siftUp(i, e);}return true;}/*** 1. 获取父节点* 2. 让元素与父节点比较,如果小于就交换位置,大于就结束* @param i 被添加元素的索引* @param e 被添加元素的值*/public void siftUp(int i, Integer e) {queue[i] = e;while (i > 0) {int parent = (i - 1) / 2;if (e > queue[parent]) {break;}swap(i, parent);i = parent;}}/***  1.返回第一个元素*  2.第一个元素与最后一个元素交换*  3.size--,最后一个元素置为null*  4.对第一个元素执行下潜操作*/public Integer poll() {if (size == 0) {throw new RuntimeException("Null");}Integer result = queue[0];swap(0, size - 1);queue[--size] = null;siftDown(0);return result;}public void swap(int i, int j) {int temp = queue[i];queue[i] = queue[j];queue[j] = temp;}/*** 1. 计算左子结点和右子节点* 2. 左子节点和右子节点中较小的一个和父节点比较(子节点的index不能大于size)* 3. 如果有比父节点小的就交换位置,直到到达叶子节点或者左子节点或右子节点没有小于父节点的就结束* @param index 要下潜元素的索引*/public void siftDown(int index) {int parent = index;int left = index * 2 + 1;int right = left + 1;if (left < size && queue[left] < queue[parent]) {parent = left;}if (right < size && queue[right] < queue[parent]) {parent = right;}// 说明找到更小的了if (parent != index) {swap(parent, index);siftDown(parent);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/186904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty第三部

继续Netty第二部的内容 一、ChannelHandler 1、ChannelHandler接口 ChannelHandler是Netty的主要组件&#xff0c;处理所有的入站和出站数据的应用程序逻辑的容器&#xff0c;可以应用在数据的格式转换、异常处理、数据报文统计等 继承ChannelHandler的两个子接口&#xff…

049-第三代软件开发-软件部署脚本(一)

第三代软件开发-软件部署脚本(一) 文章目录 第三代软件开发-软件部署脚本(一)项目介绍软件部署脚本(一)其他方式 关键字&#xff1a; Qt、 Qml、 bash、 shell、 脚本 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object…

​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第1章-绪论-思维导图】 课本里章节里所有蓝色字体的思维导图

软文推广中如何搭建媒体矩阵

媒体矩阵简单理解就是在不同的媒体平台上&#xff0c;根据运营目标和需求&#xff0c;建立起全面系统的媒体布局&#xff0c;进行多平台同步运营。接下来媒介盒子就来和大家聊聊&#xff0c;企业在软文推广过程中为什么需要搭建媒体矩阵&#xff0c;又该如何搭建媒体矩阵。 一、…

统信UOS Linux操作系统下怎么删除某个程序在开始菜单或桌面的快捷方式

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 引言 统信操作系统的开始菜单包罗万象&#xff0c;将所有应用的快捷方式都放在了开始菜单内。 虽然提供了分类展示的能力&#xff0c;但无论是分类方式还是未分类方式&#xff0c;都不能像windows一样将这…

Java之SpringCloud Alibaba【八】【Spring Cloud微服务Gateway整合sentinel限流】

一、Gateway整合sentinel限流 网关作为内部系统外的一层屏障,对内起到-定的保护作用&#xff0c;限流便是其中之- - .网关层的限流可以简单地针对不同路由进行限流,也可针对业务的接口进行限流,或者根据接口的特征分组限流。 1、添加依赖 <dependency><groupId>c…

CSDN每日一题学习训练——Java版(克隆图、最接近的三数之和、求公式的值)

版本说明 当前版本号[20231109]。 版本修改说明20231109初版 目录 文章目录 版本说明目录克隆图题目解题思路代码思路参考代码 最接近的三数之和题目解题思路代码思路参考代码 求公式的值题目解题思路代码思路参考代码 克隆图 题目 给你无向 连通(https://baike.baidu.com…

Python算法:动态规划解决0-1背包问题

动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是一种在数学、计算机科学和经济学中使用的&#xff0c;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题&#xff0c;它能够将问题…

Spark 读取ES采坑系列

目录 一、使用的插件 二、ES集群和Elasticsearch-hadoop版本问题 三、Elasticsearch-hadoop 和Scala版本以及Spark版本&#xff08;版本不匹配会有各种异常信息 一、使用的插件 <dependency><groupId>org.elasticsearch</groupId><artifactId>elas…

java入坑之类加载器

一、类加载机制 1.1类加载过程 类加载是Java虚拟机将类的字节码数据从磁盘或网络中读入内存&#xff0c;并转换成在JVM中可以被执行的Java类型的过程。类加载器是Java虚拟机的重要组成部分&#xff0c;负责加载和解析类的字节码&#xff0c;将其转换成Java虚拟机中的类对象&am…

nav2 调节纯追踪算法

纯追踪算法 纯追踪基础 The core idea is to find a point on the path in front of the robot and find the linear and angular velocity to help drive towards it. 核心思想是在机器人前方的路径上找到一个点&#xff0c;并找到一个合适的线速度和角速度&#xff0c;以驱…

[量化投资-学习笔记007]Python+TDengine从零开始搭建量化分析平台-布林带

布林带&#xff08;Bollinger Bands&#xff09;也称为布林通道、保力加通道&#xff0c;是由约翰布林格&#xff08;John Bollinger&#xff09;发明的技术分析指标。布林通道通常被用来确认资产价格波动范围。 布林通道是由三条平滑的曲线组成的趋势线图表&#xff0c;中线为…

leetcode刷题 - SQL - 中等

1. 176. 第二高的薪水 筛选出第二大 查询并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水&#xff0c;查询应该返回 null(Pandas 则返回 None) 。查询结果如下例所示。 666中等的第一题就上强度 强行解法 select max(salary) as SecondHighestSalary from Emp…

深入解析 Redis 分布式锁原理

一、实现原理 1.1 基本原理 JDK 原生的锁可以让不同线程之间以互斥的方式来访问共享资源&#xff0c;但如果想要在不同进程之间以互斥的方式来访问共享资源&#xff0c;JDK 原生的锁就无能为力了。此时可以使用 Redis 来实现分布式锁。 Redis 实现分布式锁的核心命令如下&am…

【Git】如何安装git,项目中使用git上传到远程仓库,使用git中对多人使用出现的版本问题的解决

前言&#xff1a; 一&#xff0c;Git的介绍&#xff0c;安装&#xff0c;与SVN的对比 1.1Git的介绍 Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控…

ubuntu下Anaconda环境安装GPU的pytorch(docker镜像)

实验室需要给每个人分配docker的container环境&#xff0c;为了节省系统的空间&#xff0c;打算把anaconda和深度学习的开发环境配置好拉取镜像以省时间。 基础环境配置 apt更新了清华源 安装了基础环境 gcc vim Linux文本编辑库 openssh-server ssh远程连接库 net-tools 包含…

关于Android Studio中开发Flutter配置

配置系统环境变量&#xff1a;path下 &#xff0c;flutter的bin目录下 File->Settings->Languages&Frameworks->FlutterFile->Settings->Languages&Frameworks->DartFile->Settings->Languages&Frameworks->Android SDK 确认是…

接口开发之使用C#插件Quartz.Net定时执行CMD任务工具

C#制作定时任务工具执行CMD命令 概要准备知识点实现原理thinkphp配置winform执行CMD命令读取ini配置文件定时任务Quartz.Net 完整代码Job.csIniFunc.csForm1.csconfig.ini简易定时任务工具雏形 概要 很多时候写接口上线后还会遇到很多修改&#xff0c;类似JAVA,C#,delphi制作的…

面试字节测开岗失败后,被面试官在朋友圈吐槽了......(心累)

在和朋友吃夜宵的时候&#xff0c;朋友向我吐槽说自己在参加某大厂测试面试的时候被面试官怼得哑口无言&#xff0c;场面让他一度十分尴尬 印象最深的就是下面几个问题&#xff1a; 根据你以前的工作经验和学习到的测试技术&#xff0c;说说你对质量保证的理解&#xff1f; 非…

动态规划-构建乘积数组

** 描述 给定一个数组 A[0,1,…,n-1] ,请构建一个数组 B[0,1,…,n-1] ,其中 B 的元素 B[i]A[0]A[1]…*A[i-1]A[i1]…*A[n-1]&#xff08;除 A[i] 以外的全部元素的的乘积&#xff09;。程序中不能使用除法。&#xff08;注意&#xff1a;规定 B[0] A[1] * A[2] * … * A[n-1…