返回顶部
首页 > 资讯 > 精选 >Java中堆的向下和向上调整示例分析
  • 903
分享到

Java中堆的向下和向上调整示例分析

2023-06-25 15:06:18 903人浏览 安东尼
摘要

这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、关于堆jdk1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础

这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    一、关于堆

    jdk1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础之上进行了一些元素的调整。

    1.堆的概念

    堆有最大堆和最小堆之分。
    最大(最小)堆是一棵每一个节点的元素都不小于(大于)其孩子(如果存在)的元素的树。大堆是一棵完全二叉树,同时也是一棵最大树。小堆是一棵完全二叉树,同时也是一棵最小树。
    注意: 堆中的任一子树也是堆,即大堆的子树也都是大堆,小堆亦是。

    Java中堆的向下和向上调整示例分析

    2.堆的性质

    堆中某个结点的值总是不大于或不小于其父结点的值
    堆总是一颗完全二叉树

    3.堆的存储方式

    由堆的概念可知,堆是一颗完全二叉树,因此可以层序的规则采用顺序的方式来高效存储。
    注意:对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要能够存储空结点,就会导致空间利用率比较低

    二、堆的创建

    1.堆向下调整

    对于给出的一个数据,如何将其创建为堆呢?例如下图:

    Java中堆的向下和向上调整示例分析

    仔细观察上图后发现:根结点的左右子树已经完全满足堆的性质,因此只需将根结点向下调整好即可。
    以小堆为例:

    让parent标记需要调整的结点,child标记parent的左孩子(注意:parent如果有孩子一定是先有左孩子)
    2.如果parent的左孩子存在,即child<size,进行如下操作,直到parent的左孩子不存在

    parent右孩子是否存在,如果存在则找出左右孩子中较小的孩子,使用child进行标记
    将parent与较小的孩子(也就是此时的child)比较,如果:

    parent小于较小的孩子child,这个结点已经调整
    否则:将parent与child进行交换,交换成功后,这时parent中大的元素已经向下移动,可能会导致子树不满足堆的特性,就需要继续向下调整,即parent=child,child=parent*2+1,然后循环起来

    图解如下:

    Java中堆的向下和向上调整示例分析

    代码实现:

    private void shiftDown(int parent){        //默认让child先标记左孩子---因为:parent可能有左没有右        int child=parent*2+1;        //while循环条件可以保证:parent的左孩子一定存在        //             但是不能保证parent的右孩子是否存在        while(child<size){            //1.找到左右孩子中较小的孩子            if(child+1<size&&array[child+1]<array[child]){                child+=1;            }            //2.较小的孩子已经找到了            //检测双亲和孩子之间是否满足堆的特性            if(array[parent]>array[child]){                swap(parent,child);                //大的双亲往下走,可能会导致子树又不满足堆的特性                //因此需要继续往下调整                parent=child;                child=parent*2+1;            }else{                //以parent为根的二叉树已经是堆了                return;            }        }    }

    注意: 在调整以parent为根的二叉树时,必须要满足parent的左子树和右子树已经是堆了才可以向下调整。
    时间复杂度(看最坏的情况): 从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为O(logn)。

    2.堆的创建

    向下调整的情况只能针对左右子树已经是堆了才可以调整,那假如根结点的左右子树不满足堆的特性,又该如何调整呢?例如下图:

    Java中堆的向下和向上调整示例分析

    我们要从3这里的位置开始向下调整,然后逐渐向前依次向上调整
    3这个位置很特殊,他是二叉树倒数第一个非叶子结点
    步骤:

    找到倒数第一个非叶子结点
    2.从该结点位置开始往前一直到根结点,每遇到一个结点就使用向下调整

    代码实现:

    public static void createHeap(int[] array){    //注意:倒数第一个非叶子节点刚好是最后一个节点的双亲    //最后一个结点的编号是size-1,倒数第一个非叶子节点的下标为(size-1-1)/2    int lastLeafParent=(size-2)/2;    //从倒数第一个非叶子节点位置开始,一直到根节点的位置,使用向下调整    for(int root=lastLeafParent;root>=0;root--){       shiftDown(root);    }}

    建堆的时间复杂度:
    因为堆是完全二叉树,满二叉树也是完全二叉树,为了简化计算,此处使用满二叉树来证明:
    假设满二叉树高度h

    第一层:20个结点,需要向下移动h-1层
    第二层:21个结点,需要向下移动h-2层
    第二层:22个结点,需要向下移动h-3层
    …以此类推就可以求出所有的移动步数:每一层结点数与对应移动层数相乘再整体相加
    然后再利用一定的数学巧妙运算(此处省略那些繁琐的数学公式,属实是头大)就得出T(n)=n=log(n+1)≈n

    因此:建堆的时间复杂度为O(N)。

    三、向上调整

    向上调整主要的应用场景就是在堆的插入
    堆的插入总共需要两个步骤:

    先将元素插入到堆的末尾,即最后一个孩子之后
    2.插入后如果堆的性质遭到破坏,将最后新插入的节点向上调整,直到满足堆的性质

    Java中堆的向下和向上调整示例分析

    代码实现:

    private void shiftUp(int child){        int parent=(child-1)/2;        while(child!=0){            if(array[child]<array[parent]){                swap(child,parent);                child=parent;                parent=(child-1)/2;            }else{                return;            }        }    }

    以上是“Java中堆的向下和向上调整示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

    --结束END--

    本文标题: Java中堆的向下和向上调整示例分析

    本文链接: https://lsjlt.com/news/305722.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Java中堆的向下和向上调整示例分析
      这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础...
      99+
      2023-06-25
    • Java数据结构中堆的向下和向上调整解析
      目录一、关于堆1.堆的概念2.堆的性质3.堆的存储方式二、堆的创建1.堆向下调整2.堆的创建三、向上调整一、关于堆 JDK1.8中的PriortyQueue(优先级队列)底层使用了堆...
      99+
      2024-04-02
    • 【数据结构】-向上调整算法和向下调整算法
      作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 堆 前言一、堆的...
      99+
      2023-09-17
      数据结构 php 开发语言
    • java面向对象的示例分析
      这篇文章主要介绍了java面向对象的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Java特效1、简单性人们希望构建一个无须深奥的专业训练就可以进行编程的系统,并...
      99+
      2023-06-29
    • Java中无权无向图的示例分析
      这篇文章主要介绍了Java中无权无向图的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、图的定义我们知道,前面讨论的数据结构都有一个框架,而这个框架是由相应的算法实...
      99+
      2023-06-28
    • Angular.JS中this指向的示例分析
      这篇文章主要介绍了Angular.JS中this指向的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。【this详解】1、谁最终调用函...
      99+
      2024-04-02
    • Linux中重定向的示例分析
      这篇文章给大家分享的是有关Linux中重定向的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。简介      在计算领域,重定向是大多数命令行解释器所具有的...
      99+
      2023-06-09
    • JavaScript中this指向的示例分析
      小编给大家分享一下JavaScript中this指向的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!this先看代码:方法中function t...
      99+
      2023-06-25
    • 反向Ajax的示例分析
      这篇文章主要为大家展示了“反向Ajax的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“反向Ajax的示例分析”这篇文章吧。场景1:当有新邮件的时候,网页...
      99+
      2024-04-02
    • Linux中重定向和管道的示例分析
      这篇文章主要介绍了Linux中重定向和管道的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。对shell有一定了解的人都知道,管道和重定向是 Linux 中非常实用的 ...
      99+
      2023-06-27
    • MyBatis中逆向工程的示例分析
      这篇文章主要介绍了MyBatis中逆向工程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。MyBatis的逆向工程一:什么是逆行工程...
      99+
      2024-04-02
    • Angular10中双向绑定的示例分析
      这篇文章主要介绍了Angular10中双向绑定的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。将利用@Input()和@Output...
      99+
      2024-04-02
    • Linux中io重定向的示例分析
      这篇文章给大家分享的是有关Linux中io重定向的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux io重定向是将原本要输出到屏幕中的数据信息,重新定向到某个指定的文件中,或者定向到黑洞中(/de...
      99+
      2023-06-27
    • Python面向对象和类的示例分析
      这篇文章主要为大家展示了“Python面向对象和类的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python面向对象和类的示例分析”这篇文章吧。一、两大编程思想二、类与对象简单举例:p...
      99+
      2023-06-26
    • Spring重定向的示例分析
      这篇文章主要介绍了Spring重定向的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 概述本文将重点介绍在 Spring 中实现重定向(Redirect),并将讨...
      99+
      2023-05-30
      spring
    • JS中this在各个场景下指向的示例分析
      这篇文章主要介绍JS中this在各个场景下指向的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. this 的奥秘很多时候, JS 中的 this 对于咱们的初学者很容易产...
      99+
      2024-04-02
    • Java面向对象之数组的示例分析
      这篇文章主要介绍Java面向对象之数组的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java面相对象之数组一维数组数组的说明:相同类型数据的组合。说明:①数组是引用数据类型,数组的元素可以是基本数据类型也可...
      99+
      2023-06-02
    • Java面向对象之多态的示例分析
      这篇文章主要介绍Java面向对象之多态的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!public class Polymorphism {public static&...
      99+
      2023-06-02
    • 基于SSIS事件向上传递的示例分析
      这篇文章主要介绍了基于SSIS事件向上传递的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在SSIS中,Package是Task组件...
      99+
      2024-04-02
    • Python面向对象中类和对象的示例分析
      这篇文章主要介绍了Python面向对象中类和对象的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是面向对象编程?我们是不是听过面向过程,拿来放在一起对比就比较好理...
      99+
      2023-06-22
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作