Java数据结构之堆(优先队列)


Posted in Java/Android onMay 20, 2022

堆(优先队列)是一种典型的数据结构,其形状是一棵完全二叉树,一般用于求解topk问题。根据双亲节点大于等于孩子节点或双亲节点小于等于孩子节点,可分为大顶堆和小顶堆,本文实现大顶堆。

根据大顶堆的定义,大顶堆的双亲节点大于等于其孩子节点,堆顶元素最大,对于每一个子树都是一个大顶堆,则从最后一个双亲节点进行调整为大顶堆,一直到根节点,则可构建一个大顶堆。

我们这里采用数组去存储,以heap={3,2,1,5,6,4}为例,需要一个init(int[] heap)初始化方法,从最后一个双亲节点开始将heap逐渐调整为大顶堆,其中需要使用到adjust(int[] heap, int i, int end)方法。

调整过程:从最后一个双亲节点出发,如果以当前双亲节点为根的树不符合大顶堆,则进行调整。

Java数据结构之堆(优先队列)

代码实现如下:

public void init(int[] heap) {
        //从最后一个双亲节点开始调整
        //逐渐往上进行调整
        for (int i = heap.length / 2 ; i > 0 ; i-- ) {
            this.adjust(heap, i, heap.length);
        }
    }

    public void adjust(int[] heap, int i, int end) {
        int j = i << 1;
        while (j <= end) {
            //找到两个孩子节点z中较大的节点
            if (j < end && heap[j - 1] < heap[j]) {
                j = j + 1;
            }
            //如果较大节点还小于根节点,则以当前节点为根节点的
            //二叉树已经是大顶堆,不需要进行调整
            if (heap[i - 1] > heap[j - 1]) {
                break;
            }
            //进行调整,将当前节点换到较大位置,再从当前位置进行调整
            int temp = heap[i - 1];
            heap[i - 1] = heap[j - 1];
            heap[j - 1] = temp;
            i = j;
            j = i << 1;
        }
    }

构建好了大顶堆之后,我们如何求得topk呢,此时堆顶元素为top1,我们只需要将top1元素拿走,将剩下元素调整为大顶堆,k次之后即可得到topk。

具体过程:我们将堆顶元素与最后一个元素进行交换,然后将堆顶到倒数第二个元素进行调整,依次类推。

Java数据结构之堆(优先队列)

以leetcode215数组中第k个最大元素为例:

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素

public int findKthLargest(int[] nums, int k) {
        this.init(nums);
        //找到第k大的数
        int end = nums.length;
        while (k > 1) {
            //将当前堆顶元素放到末尾,进行堆调整
            int temp = nums[0];
             nums[0] = nums[end - 1];
             nums[end - 1] = temp;
             end = end - 1;
             -- k;
             this.adjust(nums, 1, end);
        }
        return nums[0];
    }

Java数据结构之堆(优先队列)

此外,Java本身提供了优先队列集合类,但是对于这个题目效率不如自己实现的高

public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k);
        for (int num : nums) {
            if (priorityQueue.size() == k) {
                if (num > priorityQueue.peek()) {
                    priorityQueue.poll();
                    priorityQueue.add(num);
                }
                continue;
            }
            priorityQueue.add(num);
        }
        return priorityQueue.poll();
    }

Java数据结构之堆(优先队列)

到此这篇关于Java数据结构之堆(优先队列)的实现的文章就介绍到这了,更多相关Java 堆内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Java/Android 相关文章推荐
实体类或对象序列化时,忽略为空属性的操作
Jun 30 Java/Android
Spring实现内置监听器
Jul 09 Java/Android
gateway与spring-boot-starter-web冲突问题的解决
Jul 16 Java/Android
JVM钩子函数的使用场景详解
Aug 23 Java/Android
Java spring定时任务详解
Oct 05 Java/Android
Java由浅入深通关抽象类与接口(上篇)
Apr 26 Java/Android
mybatis-plus模糊查询指定字段
Apr 28 Java/Android
springboot读取nacos配置文件
May 20 Java/Android
Java处理延时任务的常用几种解决方案
Jun 01 Java/Android
解决spring.thymeleaf.cache=false不起作用的问题
Jun 10 Java/Android
IDEA中sout快捷键无效问题的解决方法
Jul 23 Java/Android
Java实现贪吃蛇游戏的示例代码
Sep 23 Java/Android
Java中Dijkstra(迪杰斯特拉)算法
Android Studio实现带三角函数对数运算功能的高级计算器
May 20 #Java/Android
springcloud整合seata
springboot读取nacos配置文件
May 20 #Java/Android
Android studio 简单计算器的编写
May 20 #Java/Android
mybatis 获取更新记录的id
May 20 #Java/Android
Android Studio 计算器开发
May 20 #Java/Android
You might like
PHP最常用的2种设计模式工厂模式和单例模式介绍
2012/08/14 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
利用PHP判断是否是连乘数字串的方法示例
2017/07/03 PHP
PHP实现的curl批量请求操作示例
2018/06/06 PHP
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
jQuery对象和DOM对象之间相互转换的方法介绍
2015/02/28 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
js正则表达式中exec用法实例
2015/07/23 Javascript
JavaScript基本数据类型及值类型和引用类型
2015/08/25 Javascript
vue2.0 中#$emit,$on的使用详解
2017/06/07 Javascript
Node.js搭建小程序后台服务
2018/01/03 Javascript
浅谈Node 调试工具入门教程
2018/03/20 Javascript
[原创]微信小程序获取网络类型的方法示例
2019/03/01 Javascript
关于layui 弹出层一闪而过就消失的解决方法
2019/09/09 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
[54:30]Liquid vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
使用python实现拉钩网上的FizzBuzzWhizz问题示例
2014/05/05 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
2019/10/11 Python
Python 生成一个从0到n个数字的列表4种方法小结
2019/11/28 Python
Scrapy框架基本命令与settings.py设置
2020/02/06 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
2020/07/09 Python
详解pycharm的python包opencv(cv2)无代码提示问题的解决
2021/01/29 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
2021/02/02 Python
HTML5+CSS3网页加载进度条的实现,下载进度条的代码实例
2016/12/30 HTML / CSS
英国马莎百货官网:Marks & Spencer
2016/07/29 全球购物
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
美赞臣新加坡官方旗舰店:Enfagrow新加坡
2019/05/15 全球购物
德国玩具商店:Planet Happy DE
2021/01/16 全球购物
擅自离岗检讨书
2014/02/11 职场文书
幼儿园中班开学寄语
2014/04/03 职场文书
融资租赁计划书
2014/04/29 职场文书
社区创先争优承诺书
2014/08/30 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
2014年语文教学工作总结
2014/12/17 职场文书
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技