堆(什么是堆以及怎样自己创建堆)

news2024/11/16 4:40:43

🎁**“我们不必非常聪明才能改变世界。我们只需要比绝大多数人更早地认识到问题,并付诸行动。”- 毛里茨·萨克斯**
🏀作者:不能再留遗憾了

📱关于作者:博主正在学习C和Java,目前有些关于leetcode刷题的专栏leetcode刷题,该专栏主要是关于数据结构方面的题目,大家有兴趣可以去看看,后面也会完善Java学习的专栏。
🚗本篇文章的主要内容:这篇文章我将为大家分享什么是堆,以及怎样自己创建堆。
在这里插入图片描述

文章目录

  • 什么是堆
  • 如何创建堆
    • 向下调整创建堆
    • 向上调整创建堆(堆的插入和删除)

什么是堆

堆(Heap)是一种数据结构,通常可以被视为一棵完全二叉树。在堆中,每个节点都满足一种特殊的条件,即父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值,这被称为堆性质。堆是一种非常常见的数据结构,通常用于实现优先队列等应用程序。常见的堆分为两种,分别是最大堆和最小堆,最大堆的根节点的关键字要比它的每个子节点的关键字都要大;最小堆的根节点的关键字要比它的每个子节点的关键字都要小。

既然堆可以被视为完全二叉树,我们就需要知道:堆可以用数组来实现,在数组中,下标为i的节点的左节点为2i+1,右节点为2i+2,父节点为(i-1)/2向下取整。这个知识对我们创建堆的时候非常关键。

在这里插入图片描述

这个就是最大堆,根节点的关键字总是大于子节点的关键字

在这里插入图片描述
最小堆,根节点的关键字总是小于子节点的关键字。

如何创建堆

向下调整创建堆

假设给你一个数组{27,15,65,49,37,34,19,18,35},你需要根据数组里面的数组创建一个最小堆或最小堆。

我们先将数组转换为完全二叉树。
在这里插入图片描述
因为提供的数组是随机的,所以我们需要看每一个子树是否符合根节点的关键字大于子节点关键字。我们从二叉树的底部开始创建,将子节点中较大的节点的值与根节点比较,如果子节点的值大于根节点,就将子节点与父节点交换,交换完成后我们需要看子节点所在的子树是否还符合最大堆,所以就需要向下调整。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
交换之后我们需要判断以15为父亲节点的子树是否符合最大堆
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以我们这个最终的二叉树就是我们需要的最大堆。

看看代码怎么写吧。

public class myHeap {
//因为堆也是数组,所以我们创建一个数组成员变量
    public int[] elem;
    //usedSize用来记录数组的大小
    public int usedSize;
    public myHeap() {
    //假设将数组大小定义为10
        this.elem = new int[10];
    }
    //初始化数组,将传入的数组赋值给elem
    public void initHeap(int[] array) {
        for (int i = 0; i < array.length; i++) {
            elem[usedSize++] = array[i];
        }
    }

    //创建
    public void creatHeap() {
    //从二叉树的底部开始创建,结束条件是parent = 0
        for (int parent = (usedSize-2)/2; parent >= 0 ; parent--) {
            shiftDown(parent,usedSize);
        }
    }

    private void shiftDown(int parent,int len) {
        int child = 2*parent+1;
        //当child  = len时,说明该子树已遍历完
        while(child < len) {
            if(child+1 < len && elem[child] < elem[child+1]) {
                child++;
            }
            if(elem[parent] < elem[child]) {
                int tmp = elem[parent];
                elem[parent] = elem[child];
                elem[child] = tmp;
                parent = child;
                child = 2*parent+1;
            }else {
                break;
            }
        }
    }
}

如果我们像创建最小堆,我们只需要将">“改成”<"就行了。

向上调整创建堆(堆的插入和删除)

如果我们不想你给我一整个数组之后我再创建堆,而是你给我一个数字我就创建堆,那么我们该怎么办呢?这里我们可以使用向上调整的思路来解决,因为我们一个一个添加数字,每次将数字添加在数组的最后,在添加了之后就会调整二叉树,所以就保证了在添加下一个数字之前,你的二叉树就已经满足了最大堆或最小堆,我们添加了一个数字之后就只需要向上做出调整即可。

在删除堆的时候我们默认删除数组的首元素,然后将数组的最后一个元素移动到数组的首地址处。移动之后我们再进行向下调整操作。

同样是这个数组{27,15,65,49,37,34,19,18,35},我们一个一个添加,看看怎么做吧。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
重复此操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
向下调整
在这里插入图片描述

public class myHeap {
    public int[] elem;
    public int usedSize;
    public myHeap() {
        this.elem = new int[10];
    }
    
    private void shiftUp(int child) {
        int parent = (child-1)/2;
        while(child > 0) {
            if(elem[child] > elem[parent]) {
                int tmp = elem[parent];
                elem[parent] = elem[child];
                elem[child] = tmp;
                child = parent;
                parent = (child-1)/2;
            }else {
                break;
            }
        }
    }

    //插入
    public void offer(int data) {
        elem[usedSize++] = data;
        if(isFull()) {
            elem = Arrays.copyOf(elem,2*elem.length);
        }
        shiftUp(usedSize-1);
    }

    public boolean isFull() {
        return usedSize > elem.length;
    }
    //删除操作
    public void pop() {
        if(isEmpty()) {
            return;
        }
        swap(elem,0,usedSize-1);
        usedSize--;
        shiftDown(0,usedSize);
    }

    public boolean isEmpty() {
        return usedSize == 0;
    }

    public void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

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

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

相关文章

【Halcon】找到设备上的 标识牌

如图&#xff0c;找到设备上的 标识牌 。 标识牌最明显的特征是比其他区域亮&#xff0c; 二值化选择出亮区域&#xff0c;再通过面积选择出目标区域。 先显示图片 *获取图片的大小 get_image_size(Image,Width,Height)*关闭窗口 dev_close_window()*打开窗口 dev_open_win…

let‘s encrypt免费证书配置https

#sudo add-apt-repository ppa:certbot/certbot #sudo apt-get update sudo apt-get install certbot 这里要停止nginx certbot certonly --agree-tos --email xxxqq.com --standalone -d 域名1 -------------------------------------------------------------------------…

MTK8788 安卓智能模块 安卓核心板方案定制

MT8768核心板是一款高性能的芯片板&#xff0c;具备以下特点&#xff1a; 1.强大的处理器&#xff1a;MT8768核心板采用联发科MTK8768平台&#xff0c;搭载八核A53处理器&#xff0c;最高主频可达2.3GHz。除此之外&#xff0c;MT8768核心板还支持多种操作系统&#xff0c;包括A…

SDMTSP:星雀优化算法NOA求解单仓库多旅行商问题(提供MATLAB代码,可更改起点及旅行商个数)

一、单仓库多旅行商问题 单仓库多旅行商问题&#xff08;Single-Depot Multiple Travelling Salesman Problem, SD-MTSP&#xff09;&#xff1a;&#x1d45a;个推销员从同一座中心城市出发&#xff0c;访问其中一定数量的城市并且每座城市只能被某一个推销员访问一次&#x…

webpack loader原理以及自定义loader

loader主要是帮助webpac将不同类型的文件转换为webpack可识别的模块。 分类&#xff1a;enforce属性 pre 前置loader&#xff0c;normal 普通loader&#xff0c;inline&#xff1a;内联loader&#xff0c;post&#xff1a;后置loader 如果不写默认是 normal类型 执行顺序&a…

ChatGPT会代替数据分析师吗?

大家好&#xff0c;我是朱小五。 最近一个多月以来&#xff0c;ChatGPT已经成为了“家喻户晓”的一个词。3月15日&#xff0c;OpenAI 开发布会宣布GPT-4&#xff0c;紧接着百度发布了自己AI产品文心一言。3月23日&#xff0c;OpenAI 宣布推出插件功能&#xff0c;赋予 ChatGPT …

【Linux Network】网络编程套接字(代码练习)—TCP

目录 1. 常用接口 2. 服务器和客户端的简单流程 3. C/S 回声通信 4. 创建子进程完成 C/S 回声通信 5. 创建孙子进程完成 C/S 回声通信 6. 创建线程完成 C/S 回声通信 7. 使用线程池完成 C/S 回声通信 Linux网络编程在✨ 本篇博文的代码虽然多&#xff0c;但都是修改一点点tcp_s…

动态规划--最长公共子序列

最长公共子序列 动态规划算法思想最长公共子序列题目最优解结构性质递归方程递归实现核心函数测试测试结果 非递归实现(画表)核心函数测试测试结果 求出具体的子序列 动态规划算法思想 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题﹐即将大规模变成…

通付盾携数智反欺诈应用防护解决方案亮相2023金融展

精彩亮相 银行数字化转型需求背景 数据驱动发展 数字经济时代&#xff0c;数据成为发展的重要资产&#xff0c;以数据驱动决策智能已是未来发展的必然趋势&#xff0c;智能化的决策将是重塑核心竞争力的关键抓手。 人工转向智能 银行的监测管理在一般业务场景中&#xff0c;…

Kyligence Zen 产品体验----设备销量商业数据

介绍 Kyligence Zen 是基于 Kyligence 核心 OLAP能力打造的一站式指标平台。凭借集业务模型、指标管理、指标加工、数据服务等于一体的解决方案,Kyligence 协助过多家金融、零售、制造企业客户搭建企业级指标平台。Kyligence Zen 是 Kyligence 基于丰富的指标平台建设实践打造…

MySQL优化二索引使用

1、索引分类 类型解释全局索引(FULLTEXT)全局索引&#xff0c;目前只有 MyISAM 引擎支持全局索引&#xff0c;它的出现是为了解决针对文本的模糊查询效率较低的问题&#xff0c;并且只限于 CHAR、VARCHAR 和 TEXT 列哈希索引(HASH)哈希索引是 MySQL 中用到的唯一 key-value 键…

《通过并行蒙特卡洛方法合成桡动脉的光电容积图(PPG),及其与体重指数(BMI)的相关性》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课…

界面控件DevExpress WPF富文本编辑器,让系统拥有Word功能(二)

DevExpress WPF控件的富文本编辑器允许开发者将文字处理功能集成到下一个WPF项目中&#xff0c;凭借其全面的文本格式选项、邮件合并以及丰富的终端用户选项集合&#xff0c;可以轻松地提供Microsoft Word功能。 DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足…

图片生成功能,ChatGPT和New Bing谁更厉害?

大家好&#xff0c;我是可夫小子&#xff0c;关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。加我&#xff0c;备注&#xff1a;chatgpt&#xff0c;拉你进群。 ChatGPT和New Bing虽然是大语言模型&#xff0c;但也有「生成图」的能力&#xff0c;它们该如何调教&#…

人员拥挤检测系统 yolov5

人员拥挤检测系统通过YOLOv5网络模型算法技术&#xff0c;人员拥挤检测系统算法模型对校园/厂区车间/街道等场景的异常的人群聚集&#xff08;出现拥挤情况&#xff09;时&#xff0c;立刻抓拍存档并通知相关人员及时处理。在介绍Yolo算法之前&#xff0c;首先先介绍一下滑动窗…

“AIGC+”将在经济社会各领域持续大放异彩

Gartner 将生成性 Al 列为 2022 年 5大影响力技术之一。MIT 科技评论也将 Al 合成数据列为 2022 年十大突破性技术之一&#xff0c;甚至将生成性 AI&#xff08;Generative Al&#xff09;称为是 AI 领域过去十年最具前景的进展。未来&#xff0c;兼具大模型和多模态模型的 AIG…

第三十六章 Unity动画编辑器

本章节我们简单介绍一下Animation动画编辑窗口&#xff0c;请大家区别之前的Animation组件哦。首先&#xff0c;我们创建一个新的场景“SampleScene4.unity”&#xff0c;然后创建一个Plane和Cube&#xff0c; 给上图中的Cube添加一个木质材质最快的办法&#xff0c;就是将一张…

易基因:2023年植物表观转录组研究的最新进展(m6A+m5C)|深度综述

大家好这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 被称为表观转录组&#xff08;epitranscriptome&#xff09;的RNA修饰正成为基因调控的广泛调控机制。由于绘制转录组范围RNA修饰测序策略的改进&#xff0c;以及分别对沉积、去除和识别RNA修饰的wri…

谈谈HMI 的自动化生成技术

人机界面&#xff08;HMI&#xff09;是自动化领域不可或缺重要组成部分。尽管人机界面系统的设计看上去并没有太大的技术门槛&#xff0c;但是设计一个HMI系统的工作量是巨大的。如果你没有足够的耐心便完成不了一个通用的HMI系统。构建UI控件库是一个似乎永远完不成的事情&am…

【SWAT水文模型】SwatWeather软件使用教程

SwatWeather软件使用教程 1 SwatWeather天气模型发生器1.1 数据输入 2 各功能介绍2.1 计算降水2.2 计算气温2.3 计算辐射2.4 计算风速2.5 计算露点 参考 1 SwatWeather天气模型发生器 SwatWeather.exe 软件只要输入一定格式要求的文件&#xff0c;就可以根据提示进行所需 数据…