优先级队列(java版)

1 实现优先队列的底层数据结构是什么?

底层结构是数组

2 实现的方法有哪些?

insert 方法 新增节点,从下往上调整堆结构。

peek方法 获得堆顶的的元素

poll 方法 删除堆顶的元素,把最后一个元素放在堆顶,调整堆结构。

3 父子节点之间的关系是什么?

父节点是i,左子节点是2*1+1,右子节点是2*i+2

如果子节点是i,父节点是(i-1)/2

4 最小堆的实现

/**
 * @Description: 使用数组实现的最小堆
 * @Date: 2021/8/5 17:20
 * @Author: fuguowen
 * @Return
 * @Throws
 */
public class MyPriorityQueue {
    //存放堆数据的数组
    private int[] data;
    //当前堆的大小
    private int size;
    //堆的最大容量
    private int capacity;

    public MyPriorityQueue(int size) {
        data = new int[size];
        this.size = 0;
        this.capacity = size;
    }

    /**
     * 获取某个结点的父结点索引
     *
     * @param i
     * @return
     */
    private int parent(int i) {
        if (i == 0) {
            throw new RuntimeException("根结点没有父结点");
        }

        return (i - 1) / 2;
    }

    /**
     * 获取某个结点的左孩子索引
     *
     * @param i
     * @return
     */
    private int lchild(int i) {
        return (2 * i) + 1;
    }

    /**
     * 获取某个结点的右孩子索引
     *
     * @param i
     * @returni
     */
    private int rchild(int i) {
        return (2 * i) + 2;
    }

    //插入元素
    public void insert(int d) {
        if (size == capacity) {
            System.out.println("堆已满");
            return;
        }

        data[size] = d;
        if (size != 0) {
            //自底向上调整
            shiftUp(size);
        }
        size++;
    }

    //移除元素
    public int poll() {

        if (size == 0) {
            System.out.println("堆已经是空的了!");
            return -1;
        }
        size--;
        int t = data[0];
        //将最后一个元素放到第一个元素位置
        data[0] = data[size];
        //然后将第一个元素下移到适当位置
        data[size] = -1;
        //自顶向下调整
        shiftDown(0);

        return t;
    }

    //删除元素,交换最后一个元素,并从上到下做堆的调整
    private void shiftDown(int i) {
        while (lchild(i) <= size - 1) {
            int j = lchild(i);
            // 让j指向他的孩子结点中的大的那一个
            if (j + 1 <= size - 1 && data[j] > data[j + 1]) {
                j = j + 1;
            }
            if (data[i] < data[j]) {
                break;
            }

            //元素下移
            int t = data[i];
            data[i] = data[j];
            data[j] = t;
            //i记录下一次要更新的元素
            i = j;
        }
    }

    //自底向上交换元素
    private void shiftUp(int index) {
        //当前元素小于父节点元素,交换元素,称为小顶堆
        while (index > 0 && data[index] < data[parent(index)]) {
            swap(data, index, (index - 1) / 2);
            index = (index - 1) / 2;
        }
    }

    /**
     * @Description: 交换两个元素
     * @Date: 2021/8/5 17:24
     * @Author: fuguowen
     * @Return
     * @Throws
     */
    public void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //获得堆顶元素
    public Integer peek() {
        return (size == 0) ? null : data[0];
    }

    public static void main(String[] args) {
        int[] arr = {3, 2, 1, 3, 5, 6, 2, 8, 9, 4};
        int k = 3;
        MyPriorityQueue queue = new MyPriorityQueue(k);
        for (int i = 0; i < k; i++) {
            queue.insert(arr[i]);
        }
        for (int j = k; j < arr.length; j++) {
            Integer peek = queue.peek();
            if (arr[j] >= peek) {
                queue.poll();
                queue.insert(arr[j]);
            }
        }
        System.out.println(queue.peek());
    }
}

5 最大堆的实现

package com.mashibing.my.test202304;

public class Test019 {
    /**
     * @Description: 使用数组实现的最大堆
     * @Date: 2021/8/5 17:20
     * @Author: fuguowen
     * @Return
     * @Throws
     */
    public static class MyPriorityQueue {
        //存放堆数据的数组
        private int[] data;
        //当前堆的大小
        private int size;
        //堆的最大容量
        private int capacity;

        public MyPriorityQueue(int size) {
            data = new int[size];
            this.size = 0;
            this.capacity = size;
        }

        /**
         * 获取某个结点的父结点索引
         * @param i
         * @return
         */
        private int parent(int i) {
            if (i == 0) {
                throw new RuntimeException("根结点没有父结点");
            }

            return (i - 1) / 2;
        }

        /**
         * 获取某个结点的左孩子索引
         *
         * @param i
         * @return
         */
        private int lchild(int i) {
            return (2 * i) + 1;
        }

        /**
         * 获取某个结点的右孩子索引
         *
         * @param i
         * @returni
         */
        private int rchild(int i) {
            return (2 * i) + 2;
        }

        //插入元素
        public void insert(int d) {
            if (size == capacity) {
                System.out.println("堆已满");
                return;
            }
            data[size] = d;
            if (size != 0) {
                //自底向上调整
                shiftUp(size);
            }
            size++;
        }

        //移除堆顶元素
        public int poll() {

            if (size == 0) {
                System.out.println("堆已经是空的了!");
                return -1;
            }
            size--;
            int t = data[0];
            //将最后一个元素放到第一个元素位置
            data[0] = data[size];
            //然后将第一个元素下移到适当位置
            data[size] = -1;
            //自顶向下调整
            shiftDown(0);

            return t;
        }
        public  int maximum(){
            if (size == 0) {
                System.out.println("堆为空");
                return -1;
            }
            return data[0];
        }


        //删除元素,交换最后一个元素,并从上到下做堆的调整
        private void shiftDown(int i) {
            int l = lchild(i);
            int r = rchild(i);
            int max = i;
            if (l < size && data[l] > data[i]) {
                max = l;
            }
            if (r < size && data[r] > data[max]) {
                max = r;
            }
            if (max != i) {
                swap(data, max, i);
                shiftUp(max);
            }
        }

        //自底向上交换元素
        private void shiftUp(int i) {
            //当前元素小于父节点元素,交换元素,称为小顶堆
            int p = parent(i);
            while (i > 0 && data[i] > data[p]) {
                swap(data, i, p);
                i = (i - 1) / 2;
            }
        }

        /**
         * @Description: 交换两个元素
         * @Date: 2021/8/5 17:24
         * @Author: fuguowen
         * @Return
         * @Throws
         */
        public void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        //获得堆顶元素
        public Integer peek() {
            return (size == 0) ? null : data[0];
        }

        public static void main(String[] args) {
            int[] arr = {3, 2, 1, 3, 5, 6, 2, 8, 9, 4};
            int k = 3;
            MyPriorityQueue queue = new MyPriorityQueue(k);
            for (int i = 0; i < k; i++) {
                queue.insert(arr[i]);
            }
            for (int j = k; j < arr.length; j++) {
                Integer peek = queue.peek();
                if (arr[j] >= peek) {
                    queue.poll();
                    queue.insert(arr[j]);
                }
            }
            System.out.println("容量:" + k + "  指定容量的小顶堆的堆顶元素:" + queue.peek());
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 整合 JSP和MyBatis

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Vue 10 - 计算属性

介绍 Vue.js中的计算属性是一种可以根据已有的数据来计算并返回新的数据的属性。与简单的属性不同&#xff0c;计算属性不仅依赖于组件实例的数据状态&#xff0c;而且还可以根据其他计算属性的值进行计算。这使得我们能够通过组合现有的数据来派生出一些新的数据&#xff0c;…

不愧是腾讯架构师珍藏的“redis深度笔记(全彩版)”这细节讲解,神了

前言 说到 Redis 相信对于我们这些程序员来说太熟悉了&#xff0c;Redis 凭借着自己超高的超高的性能、完美的文档、简洁易懂的源码和丰富的客户端库支持&#xff0c;很快就在国内的互联网市场占据了一席之地&#xff0c;得到了广大用户的一致好评&#xff0c;随着国内外使用 …

【Linux】创建子进程

进程概念-创建子进程程序计数器&上下文信息创建子进程程序计数器&上下文信息 我们知道&#xff0c;当计算机在运行程序的时候实际上是在执行汇编指令 但是存在一个问题&#xff0c;一台计算机中有许多个进程&#xff0c;而CPU只有几个&#xff0c;那么就意味着&#x…

项目管理方法不是最重要的,成功完成项目真正需要什么?

当今项目管理的两个方向正在发展&#xff1a;瀑布式和敏捷式。这两种方法都有优点和缺点&#xff0c;下面将介绍最流行和适用的方法。 瀑布式 这种方法的主要代表是PRINCE2&#xff0c;该模型基于这样一个事实&#xff0c;即我们从一开始就知道我们想要生产什么&#xff0c;…

MySQL逻辑架构

讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 1. 逻辑架构剖析 1.1 服务器处理客户端请求 首先MySQL是典型的C/S架构&#xff0c;即Client/Server 架构&#xff0c;服务器端程序使用的mysqld…

2023年第十四届蓝桥杯将至,来看看第十二届蓝桥杯javaB组题目如何

ฅ(๑˙o˙๑)ฅ 大家好, 欢迎大家光临我的博客&#xff1a;面向阿尼亚学习 算法学习笔记系列持续更新中~ 文章目录一、前言二、2021年蓝桥杯javaB组省赛真题目录A:ASC[5分]思路⭐代码&#x1f31f;B 卡片(5分)思路⭐代码&#x1f31f;C 直线(10分)思路⭐代码&#x1f31f;D 货…

UNIX环境高级编程——标准I/O库

5.1 引言 本章讲述标准I/O库&#xff0c;这个库由ISO C标准说明。 5.2 流和FILE对象 对于标准I/O库&#xff0c;它们的操作是围绕流&#xff08;stream&#xff09;进行的&#xff0c;当用标准I/O库打开或创建一个文件时&#xff0c;就使一个流与一个文件关联&#xff1b;标…

Linux必会100个命令(五十八)dnf命令

DNF不是那个游戏。 dnf是rpm软件包管理器。 它跟yum类似&#xff0c;但是未来可能替代yum。 在CentOS7以后dnf和yum都可以使用。 如果没有安装dnf&#xff0c;可以使用如下命令&#xff1a; yum install epel-release yum install dnf 使用--version查看 dnf版本 使用re…

ToBeWritten之PWN入门介绍/环境搭建

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…

【JavaWeb】5—Servlet

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…

美摄汽车数据匿名化方案:精准、高效、低耗

近年来随着智能网联汽车的升级迭代&#xff0c;车辆采集数据的量级与敏感度也日渐提升。以车载摄像头为例&#xff0c;当前智能汽车车身配备的摄像头数量逐渐增加&#xff0c;采集到的信息也更加复杂多样。根据来源主体不同&#xff0c;车联网敏感数据大致可以划分为以下几类&a…

SMT丨工艺特点及详细生产工艺流程

目录SMT丨工艺特点及详细生产工艺流程一、表面组装技术SMT现状二、表面组装技术SMT的工艺与特点1、SMT工艺2、下面就几个对再流焊质量影响较大的因素进行讨论。3、SMT的特点&#xff1a;三、表面组装技术SMT的发展趋势1、窄间距技术&#xff08;FPT&#xff09;是SMT发展的必然…

【云原生】k8s Service 实现服务发现和负载均衡

文章目录前言Service 介绍Service 的四种类型及使用方式Service 的定义和使用通过命令创建服务查看创建的服务情况不指定 Selectors 的服务Headless 服务Service 工作原理及原理图Ingress 讲解集群外部如何访问服务总结前言 在容器编排系统中&#xff0c;如 Kubernetes&#x…

NLP / LLMs中的Temperature 是什么?

ChatGPT, GPT-3, GPT-3.5, GPT-4, LLaMA, Bard等大型语言模型的一个重要的超参数 大型语言模型能够根据给定的上下文或提示生成新文本&#xff0c;由于神经网络等深度学习技术的进步&#xff0c;这些模型越来越受欢迎。可用于控制生成语言模型行为的关键参数之一是Temperature …

思维导图软件哪个好?安利八款好用的思维导图软件

当你需要表达和整理复杂的想法、计划和项目时&#xff0c;思维导图软件可以是非常有用的工具。不同的思维导图软件有不同的功能和特点&#xff0c;选择适合自己的软件可以让你更高效地工作和学习。但是你了解思维导图软件哪个好呢&#xff1f;下面就给大家安利八款简单好用的思…

Python 自动化指南(繁琐工作自动化)第二版:十二、网络爬取

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter12/ 在那些没有 Wi-Fi 的罕见、可怕的时刻&#xff0c;我意识到我在电脑上做的事情有多少是我在互联网上做的。出于纯粹的习惯&#xff0c;我会发现自己试图查看电子邮件&#xff0c;阅读朋友的 Twitter 信息&am…

C生万物 | 校招热门考点 —— 结构体内存对齐

文章目录一、前言结构体偏移量计算&#xff1a;offsetof二、规则介绍例题的分解与细说三、习题演练1、练习①2、练习②四、为什么存在内存对齐?1、平台原因(移植原因)2、性能原因五、如何修改默认对齐数六、实战演练✍一道百度笔试题&#xff1a; offsetof 宏的实现&#x1f4…

AIGC技术周报|ChatDoctor:哪里不舒服;HuggingGPT:连接大模型和机器学习社区;ChatGPT真的鲁棒吗?

AIGC通过借鉴现有的、人类创造的内容来快速完成内容创作。ChatGPT、Bard等AI聊天机器人以及DallE 2、Stable Diffusion等文生图模型都属于AIGC的典型案例。「AIGC技术周报」将为你带来最新的paper、博客等前瞻性研究。 1.ChatDoctor&#xff1a;哪里不舒服&#xff1f; 通用领…

双周赛101(模拟、动态规划、中位数贪心+裴蜀定理、BFS)

文章目录6327. 从两个数字数组里生成最小数字模拟6328. 找到最大开销的子字符串同向双指针动态规划(相似)[53. 最大子数组和](https://leetcode.cn/problems/maximum-subarray/)&#x1f383;[6329. 使子数组元素和相等](https://leetcode.cn/problems/make-k-subarray-sums-eq…
最新文章