数据结构六:堆

news2024/9/20 14:41:52

前言:上一篇我们讲了二叉树,你知道吗?堆的底层是一棵完全二叉树。这样说会不会就会觉得熟悉了。

目录

1.堆的概念及存储方式

 2:堆的创建

2.1:向下调整

3.堆的插入和删除

3.1:堆的插入

3.2:堆的删除

4.PriorityQueue的特性-----优先级队列

4.1常用接口介绍

4.1.1:优先级队列的构造

 4.1.2:插入/删除/获取

5:应用


1.堆的概念及存储方式

它的所有元素按照完全二叉树的顺序存储方式存储在一个一维数组中。

如果i为0,表示根节点。否则父亲节点:(i-1)/2

如果i*2+1小于节点个数。左孩子:2*i+1

如果i*2+2小于节点个数。右孩子:2*i+2

大堆:根节点比左右孩子都大。

小堆:根节点比左右孩子都小。

存储方式:堆是一颗完全二叉树,因此可以层序的规则采用顺序的方式来高效存储。


 2:堆的创建

public class MyHeap {
    //它的存储结构是一维数组
    public int [] elem;
    public int usedSize;//记录数组中的有效元素个数
    public  static  final int DEFIND_SIZE=10;//数组容量
    //开辟数组空间
    public   void createHeap(){
        elem=new int [DEFIND_SIZE];
    }
    

2.1:向下调整

  public void CreateMinHeap(){
        for (int parent =(usedSize-1)/2 ; parent>=0; parent--) {
            shiftDown(parent,usedSize);//向下调整
        }
    }
    public  void shiftDown(int parent,int len){
        int child=parent*2+1;
       //必须有左孩子
        while(child<len){
            //判断它是否有右孩子,看谁的值比较小
            if(child+1<len&&elem[child+1]<elem[child]){
                child++;//child是最小的
            }//判断父亲节点和孩子节点那个小
            if(elem[parent]>elem[child]){//大于就交换
                swap(elem,parent,child);
                parent=child;
                child=parent*2+1;
            }else{//不大于
                break;
            }
    }
}
public void swap(int [] elem,int i,int j){
        int tmp=elem[i];
        elem[i]=elem[j];
        elem[j]=tmp;
    }
}

3.堆的插入和删除

3.1:堆的插入

堆的插入总共需要两个步骤

1.判断空间够不够,够就将元素放到底层空间中;不够,扩容

2.将最后新插的节点向上调整,知道堆的性质。

   //堆的插入
    public void offer(int val){
        //判断空间是否够
        if (isFull()){
            //满了,扩容
            //以二倍扩容
            elem= Arrays.copyOf(elem,elem.length*2);
        }//没有满
       elem[usedSize]=val;
        shiftUp(usedSize);
        usedSize++;//记录有效元素个数加加
    }
    //向上调整
    public void shiftUp(int child){
        //找到它的父亲
        int parent=(child-1)/2;
        while(parent>=0){
            if(elem[parent]>elem[child]){
                swap(elem,parent,child);
                child=parent;
                parent=(child-1)/2;
            }else{
                break;
            }
        }
    }
    public boolean isFull(){
        //如果有效元素个数等于大于数组长度
        //说明数组满了
        return  usedSize>=elem.length;
    }
}

3.2:堆的删除

注意:堆的删除一定时堆顶元素

1.将最后一个元素和堆顶元素交换。

2.将有效元素个数减减。

3.向下调整,符合堆的性质

 public int pop(){
        //判断堆是否为空
        if(isEmpty()){
            return -1;
        }//不为空,和最后一个元素交换位置
        int tmp=elem[0];
        swap(elem,0,usedSize-1);
        //有效元素减
        //向下调整
        shiftDown(0,usedSize-1);
        return tmp;
    }

4.PriorityQueue的特性-----优先级队列

优先级队列的底层是堆。

注意事项:

1.PriorueueQueue中放置的元素必须是能够比较大小,否则会抛出ClassCastException异常。

2.不能插入null对象.否则会抛出NullpointerException

3.没有容量限制,可以插入任意元素。

4.PriorityQueue默认情况是小堆


4.1常用接口介绍

4.1.1:优先级队列的构造


 4.1.2:插入/删除/获取

函数名功能介绍
boolean offer(E e)插入e,成功返回true.
E peek()获取优先级最高的元素,如果为空,返回null
int size()获取有效元素个数
E poll()移除优先级最高的元素并返回,如果为空,返回null
void clear()清空
boolean isEmpty()检查优先级队列是否为空,空返回null


扩容说明:

如果容量小于64是按照2倍方式扩容

如果容量大于64是按1.5倍方式扩容

如果容量大于最大值,按照最大值来进行扩容


5:应用

5.1:Top-k问题

1.用数据集合中前K个元素来建堆

1.1:前K个最大的元素,建小堆

1.2:前k个最小的元素,建大堆。

2。用剩下的元素依次和堆顶元素来比较,不满足则替换堆顶元素。

https://leetcode.cn/problems/smallest-k-lcci/

class Solution {
     public int[] smallestK(int[] arr, int k){
        //判断k是否大于1,数组是否为空
        if(arr.length==0||k<1){
            return  new int[0];
        }
        PriorityQueue<Integer> p1=new PriorityQueue<>
                (k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        //将前k个元素,建成大堆
        for (int i = 0; i <k ; i++) {
            p1.offer(arr[i]);
        }
        //把剩下的元素和堆顶元素相比
        for (int i = k; i <arr.length ; i++) {
            int tmp = p1.peek();
            if (tmp >arr[i]) {
                p1.poll();
                p1.offer(arr[i]);
            }
        }
            //将堆的元素赋值到数组里
        int [] ret=new int[k];
        for (int i = 0; i <k ; i++) {
            ret[i]= p1.poll();
        }
        return ret;
    }
}

总结;

以上就是我总结的堆的知识点。若有错误,请各位铁铁留言纠错。若感觉不错,请一键三连。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Web的商城后台管理系统的设计与实现

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Oracle和MySQL查询所有的表信息和字段信息

Oracle和MySQL查询所有的表信息和字段信息1. MySQL1.1 查询表1.2 查询字段1.2.1 方式1->SHOW FULL COLUMNS1.2.2 方式2->information_schema.COLUMNS1.3 查表和字段1.4 查表和字段-->转程Oracle需要的数据类型2. Oracle2.1 查表和字段的单表查询2.2 整理查表和字段的s…

超详细的JUnit单元测试介绍

前言 本文为JUnit单元测试相关知识&#xff0c;下边将对JUnit单元测试概念&#xff0c;JUnit优点&#xff0c;JUnit安装与使用&#xff0c;JUnit运行流程与常用注解&#xff0c;JUnit测试套件使用及参数化设置&#xff0c;JUnit断言等进行详尽介绍~ &#x1f4cc;博主主页&…

大数据Hadoop之——Apache Hudi 与 Presto/Trino集成

文章目录一、概述二、Trino 环境部署1&#xff09;安装JDK2&#xff09;安装python3&#xff09;安装Trino1、下载解压并配置环境变量2、修改配置3、启动服务4、测试验证三、在Hive中创建表关联Hudi表1&#xff09;添加jar包2&#xff09;创建库表关联Hudi四、Hudi 与 Trino集成…

SpringCloud Alibaba系列 Sentinel(三)

高并发下的微服务容错方案&#xff1f; 限流、熔断、降级 1&#xff1a;限流 在高并发系统中一定要用&#xff0c;高并发的所有请求进来&#xff0c;不是让每个请求都打到后台集群的&#xff0c;后台集群有它的消费能力&#xff0c;应该在它消费能力之内放行请求&#xff0c;…

Hadoop HA集群全是standBy解决办法

文章目录原理解决方案原理 hadoop集群配置HA后&#xff0c;会存在多个namenode&#xff0c;但是同一时间仅有一台NN为Active的状态&#xff0c;其他NN都是StandBy的状态。 上图是hadoop集群配置HA的原理图&#xff0c;从上图我们可以看到多个NN的状态切换&#xff0c;是依靠Z…

linux命令与makefile学习

linux命令与makefile学习文件权限通配符*常用命令makefilegcc与g区别&#xff1a;Linux上有一句话&#xff1a;一切皆文件 普通文件 “-” 目录文件 “d” &#xff08;directory&#xff09; 管道文件 “p” &#xff08;piping&#xff09; 链接文件“l” &#xff08;li…

SAP FICO银行账户余额查询表开发说明书(包括开发源代码、测试样例及FS)

程序说明 满足财务银行账户余额查询明细的需求; 支持财务实时查看银行余额数据。 筛选界面 序号 栏位标题 字段类型 是否必须 是否为范围

【pwn】2022 祥云杯 部分wp

【pwn】2022 祥云杯 部分wp 前言 又是一年的祥云杯&#xff0c;相比去年我啥也不会写&#xff0c;今年起码写了几个签到… 又被队友带飞咯 protool Google的Protobuf&#xff0c;参考学习连接 https://bbs.pediy.com/thread-270004.htm 发现了栈溢出&#xff0c;protobuf…

Unity技术手册-UGUI零基础详细教程-Toggle切换

往期文章分享点击跳转>《导航贴》- Unity手册&#xff0c;系统实战学习点击跳转>《导航贴》- Android手册&#xff0c;重温移动开发 本文约3千字&#xff0c;新手阅读需要7分钟&#xff0c;复习需要2分钟 【收藏随时查阅不再迷路】 &#x1f449;关于作者 众所周知&#…

2.6 Python 基本数据类型

1. 数据类型 类型是变量所指的内存中对象的类型. 内置的type()函数可以用来查询变量所指的对象类型。Python 3中有六个标准的数据类型: Numbers(数字), String(字符串), List(列表), Tuple(元组), Sets(集合), Dictionary(字典).2. Numbers 数字型 Python 有三种数字类型 in…

SpringMVC基本配置

小常规 springmvc的处理器对应的bean必须按照规范格式开发&#xff0c;为避免加入无效的bean可通过bean加载过滤器进行包含设定或排除设定&#xff0c;表现层bean标注通常设定为Controller在此发现图片没有加载出来回到程序去分析当发起一个请求以后DispatcherServlet配置拦截所…

【JVM技术专题】 深入分析class字节码指令方法调用详解「原理篇」

方法调用详解 ​ 调用目标在程序代码写好、编译器进行编译时就必须确定下来&#xff0c;这类方法的调用称为解析。 解析 ​ 在Java语言中符合**“编译期可知&#xff0c;运行期不可变”**这个要求的方法&#xff0c;主要包括静态方法和私有方法两大类&#xff0c;前者与类型…

【JavaScript】网页轮播图

目录HTML搭建功能实现小圆圈事件左右按钮事件自动播放轮播图也叫焦点图&#xff0c;是网页中比较常见的网页特效。功能&#xff1a;鼠标经过轮播图模块&#xff0c;左右按钮显示&#xff0c;离开隐藏左右按钮。点击右侧按钮一次&#xff0c;图片往左播放一张&#xff0c;以此类…

UACANet: Uncertainty Augmented Context Attention for Polyp Segmentation代码补充

上一篇看了文章创新点的代码&#xff0c;现在看一下train文件等其余的文件。 看主函数&#xff1a; import os import torch import argparse import tqdm import sysimport cv2 import torch.nn as nn import torch.distributed as distfrom torch.optim import Adam, SGD fr…

CVE-2022-21907 Microsoft Windows HTTP 协议栈远程代码执行漏洞复现

目录 0x01 声明&#xff1a; 0x02 简介&#xff1a; 0x03 漏洞概述&#xff1a; 0x04 影响版本&#xff1a; 0x05 环境搭建&#xff1a; 下载&#xff1a; 开启IIS&#xff1a; 0x06 漏洞复现&#xff1a; 利用POC&#xff1a; 0x07 流量分析&#xff1a; 客户端&am…

算法提升 (三)基础数据结构

作者&#xff1a;小萌新 专栏&#xff1a;算法提升 作者简介&#xff1a;大二学生 希望能够和大家一起进步&#xff01; 内容简介&#xff1a;简单介绍基本数据结构的简单面试题 不负韶华 链表 阅读这篇文章之前需要有初阶数据结构的基础 关于链表的结构如果还有不了解的同学…

智能AI创意图片编辑Luminar Neo

Luminar Neo是Mac上的智能AI技术编辑软件背景替换、图像层、除尘、重新照明选项等&#xff0c;从而实现精确掌控。同时在这款软件中还拥有可简化复杂的编辑程序&#xff0c;如此一来用户即可将自己大脑中想象的愿景变为现实&#xff0c;让使用者能有多大胆的想法都可以在这款软…

深度学习 卷积神经网络原理

深度学习 卷积神经网络原理一、前言二、全连接层的局限性三、卷积层3.1 如何进行卷积运算&#xff1f;3.2 偏置3.3 填充3.4 步长3.5 卷积运算是如何保留图片特征的&#xff1f;3.6 三维卷积3.7 多种特征提取四、池化层五、全连接层六、参考资料一、前言 本文分析了全连接层存在…

burpsuite利用sql注入漏洞猜解数据库名称

目录 一、前提条件 二、burpsuite猜解数据库名 &#xff08;一&#xff09;设置firefox代理 &#xff08;二&#xff09;使用burpsuite的proxy模块截取数据包 &#xff08;三&#xff09;将proxy截取的数据包右击发送到intruder模块 &#xff08;四&#xff09;设置2个变量…