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 相关文章推荐
Spring Bean的实例化之属性注入源码剖析过程
Jun 13 Java/Android
Spring boot应用启动后首次访问很慢的解决方案
Jun 23 Java/Android
Java日常练习题,每天进步一点点(38)
Jul 26 Java/Android
Java比较两个对象中全部属性值是否相等的方法
Aug 07 Java/Android
简述Java中throw-throws异常抛出
Aug 07 Java/Android
IDEA2021.2配置docker如何将springboot项目打成镜像一键发布部署
Sep 25 Java/Android
Java 实战项目之家居购物商城系统详解流程
Nov 11 Java/Android
Android中View.post和Handler.post的关系
Jun 05 Java/Android
利用Java连接Hadoop进行编程
Jun 28 Java/Android
SpringBoot详解自定义Stater的应用
Jul 15 Java/Android
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
Jul 15 Java/Android
基于Android10渲染Surface的创建过程
Aug 14 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使用PDO操作MySQL数据库实例
2014/12/30 PHP
19个Android常用工具类汇总
2014/12/30 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
js浮点数精确计算(加、减、乘、除)
2013/12/26 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
JavaScript框架是什么?怎样才能叫做框架?
2015/07/01 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
jQuery Ajax和getJSON获取后台普通json数据和层级json数据用法分析
2016/06/08 Javascript
详解jQuery的表单验证插件--Validation
2016/12/21 Javascript
js中自定义react数据验证组件实例详解
2018/10/19 Javascript
react+ant design实现Table的增、删、改的示例代码
2018/12/27 Javascript
JS实现数组去重及数组内对象去重功能示例
2019/02/02 Javascript
axios实现简单文件上传功能
2019/09/25 Javascript
vue实现的封装全局filter并统一管理操作示例
2020/02/02 Javascript
ng-alain的sf如何自定义部件的流程
2020/06/12 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
用Python解决计数原理问题的方法
2016/08/04 Python
python如何获取服务器硬件信息
2017/05/11 Python
Python建立Map写Excel表实例解析
2018/01/17 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
python实现简单的tcp 文件下载
2020/09/16 Python
自定义Django_rest_framework_jwt登陆错误返回的解决
2020/10/18 Python
CSS3 实现倒计时效果
2020/11/25 HTML / CSS
New Balance比利时官方网站:购买鞋子和服装
2021/01/15 全球购物
List, Set, Map是否继承自Collection接口?
2016/05/16 面试题
.NET面试题:什么是值类型和引用类型
2016/01/12 面试题
《曹刿论战》教学反思
2014/03/02 职场文书
最新优秀教师个人先进事迹材料
2014/05/06 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
2014年社区综治工作总结
2014/11/17 职场文书
储备店长岗位职责
2015/04/14 职场文书
2015年生产车间工作总结
2015/04/22 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书
vue+spring boot实现校验码功能
2021/05/27 Vue.js