iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java数据结构中堆的向下和向上调整解析
  • 362
分享到

Java数据结构中堆的向下和向上调整解析

2024-04-02 19:04:59 362人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录一、关于堆1.堆的概念2.堆的性质3.堆的存储方式二、堆的创建1.堆向下调整2.堆的创建三、向上调整一、关于堆 jdk1.8中的PriortyQueue(优先级队列)底层使用了堆

一、关于堆

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

1.堆的概念

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

在这里插入图片描述

2.堆的性质

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

3.堆的存储方式

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

二、堆的创建

1.堆向下调整

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

在这里插入图片描述

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

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

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

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

图解如下:

在这里插入图片描述

代码实现:


    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.堆的创建

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

在这里插入图片描述

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

1.找到倒数第一个非叶子结点
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)。

三、向上调整

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

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

在这里插入图片描述

代码实现:


    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数据结构中堆的向下和向上调整解析的文章就介绍到这了,更多相关Java 数据结构 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java数据结构中堆的向下和向上调整解析

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java数据结构中堆的向下和向上调整解析
    目录一、关于堆1.堆的概念2.堆的性质3.堆的存储方式二、堆的创建1.堆向下调整2.堆的创建三、向上调整一、关于堆 JDK1.8中的PriortyQueue(优先级队列)底层使用了堆...
    99+
    2024-04-02
  • Java中堆的向下和向上调整示例分析
    这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础...
    99+
    2023-06-25
  • 【数据结构】-向上调整算法和向下调整算法
    作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 堆 前言一、堆的...
    99+
    2023-09-17
    数据结构 php 开发语言
  • java数据结构中单向链表和双向链表的介绍
    这篇文章主要讲解了“java数据结构中单向链表和双向链表的介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java数据结构中单向链表和双向链表的介绍”吧!目录单向链表单链表图解代码双向链表...
    99+
    2023-06-20
  • Java数据结构之双向链表图解
    双向链表(Doubly linked list) 什么是双向链表? 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的...
    99+
    2024-04-02
  • 深入了解Java数据结构和算法之堆
    目录1、堆的定义2、遍历和查找3、移除4、插入5、完整的Java堆代码总结1、堆的定义 ①、它是完全二叉树,除了树的最后一层节点不需要是满的,其它的每一层从左到右都是满的。注意下面两...
    99+
    2024-04-02
  • JavaScript数据结构之双向链表和双向循环链表的示例分析
    这篇文章主要为大家展示了“JavaScript数据结构之双向链表和双向循环链表的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript数据结...
    99+
    2024-04-02
  • Java数据结构中的堆怎么应用
    本篇内容介绍了“Java数据结构中的堆怎么应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、堆的创建1、向下调整(以小堆为例) &nbs...
    99+
    2023-06-29
  • Java数据结构之双向链表的实现
    目录1 双向链表1.1 双向链表介绍1.2 双向链表实现思路2 双向链表实现完整代码2.1 节点类 Student.java2.2 双向链表实现类 StudentDoubleLink...
    99+
    2022-11-13
    Java 数据结构 双向链表 Java 双向链表
  • Java数据结构之有向图的拓扑排序详解
    目录前言拓扑排序介绍检测有向图中的环实现思路API设计代码实现基于深度优先的顶点排序实现思路API设计代码实现拓扑排序API设计代码实现测试验证前言 在现实生活中,我们经常会同一时间...
    99+
    2022-11-13
    Java有向图 拓扑排序 Java 有向图 Java 拓扑排序
  • 带你了解Java数据结构和算法之无权无向图
    目录1、图的定义①、邻接:②、路径:③、连通图和非连通图:④、有向图和无向图:⑤、有权图和无权图:2、在程序中表示图①、顶点:②、边:3、搜索①、深度优先搜索(DFS)②、广度优先搜...
    99+
    2024-04-02
  • Java 超详细讲解数据结构中的堆的应用
    目录一、堆的创建1、向下调整(以小堆为例)  2、创建堆3、创建堆的时间复杂度 二、堆的插入和删除1、堆的插入2、堆的删除 三、堆的应用1、堆排序2、t...
    99+
    2024-04-02
  • Java两整数相除向上取整的方式详解(Math.ceil())
    目录前言:方式一: 添加三目运算符逻辑代码方式二:使用ceil函数方式三:其他逻辑最后总结附:java向上取整函数Math.ceil()前言: Java中两个整数相除,如果不能整除,...
    99+
    2024-04-02
  • Java数据结构之最小堆和最大堆的原理及实现详解
    目录一、前言二、堆的数据结构三、堆的代码实现1. 实现介绍2. 入堆实现3. 出堆实现4. 小堆实现5. 大堆实现一、前言 堆的历史 堆的数据结构有很多种体现形式,包括;2-3堆、B...
    99+
    2024-04-02
  • C语言数据结构之单向链表详解分析
    链表的概念:链表是一种动态存储分布的数据结构,由若干个同一结构类型的结点依次串连而成。 链表分为单向链表和双向链表。 链表变量一般用指针head表示,用来存放链表首结点的地址。 每个...
    99+
    2024-04-02
  • C语言数据结构中堆排序的分析总结
    目录一、本章重点 二、堆2.1堆的介绍(三点)2.2向上调整2.3向下调整2.4建堆(两种方式)三、堆排序一、本章重点  堆向上调整向下调整堆排序 二、堆 2.1...
    99+
    2024-04-02
  • Java数据结构之有向图设计与实现详解
    目录前言定义及相关术语API设计代码实现前言 在实际生活中,很多应用相关的图都是有方向性的,最直观的就是网络,可以从A页面通过链接跳转到B页面,那么a和b连接的方向是a->b,...
    99+
    2022-11-13
    Java数据结构有向图 Java有向图
  • java数据结构单向链表的操作有哪些
    本文小编为大家详细介绍“java数据结构单向链表的操作有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“java数据结构单向链表的操作有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。关于节点数据添加:尾添...
    99+
    2023-07-06
  • 如何调整2000运行中的数据库结构
    如何调整2000运行中的数据库结构,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。开发过程中的数据库结构结构,不可避免的会需要反复的修改。最麻烦...
    99+
    2024-04-02
  • PHP 队列和堆栈的数据结构实现详解
    队列遵循“先进先出”原则,可使用数组或链表实现;堆栈遵循“后进先出”原则,同样可使用数组或链表实现。具体实现方式包括:队列数组实现、队列链表实现、堆栈数组实现、堆栈链表实现。实战案例演示...
    99+
    2024-05-07
    php 队列
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作