堆排序-优先级队列

news2024/12/29 17:13:59

我们用堆排来实现优先级队列,那么优先级队列是什么,就是 我们给每一个任务都添加一个优先级,优先级越高执行的越早我们用,但是我们怎么能按照顺序优先拿到优先级高的任务呢,我们可以用排序 来进行,也可以用堆 排序来进行,效率更高

 如上图 索引0 为 根节点 也就是parent,那么我们如何找到 他的 叶子节点呢?  如果用比大小直接排序的话,就不是堆排序,堆排序本质 就是用有序数组的形式,来形成树型结构,当我们知道 parent结点之后,他的child节点就遵循如下规律

parent=(child-1)/2 

上浮    

当我们添加元素的时候

我们可以先往数组的尾部添加,如上图的话 也就是 下一个元素要添加到的位置 就是数组的索引7 的位置,我们根据 索引7 为child 节点,然后根据上面的公式 找到 他的 parent节点为 索引3.,然后跟索引3的任务比较优先级,如果优先级比索引三处的任务大,我们把当前child节点的任务更新成parent节点的任务,然后我们在把child 节点更新成索引三,并且把再往上找一个parent节点,继续比较优先级。(翻译过来是 如果 索引7 的优先级比索引三的 优先级高,把索引三的任务 赋给索引7,然后 修改新的child节点为索引3,再继续找 parent节点,直到parent节点索引为0,或者parent节点的优先级比child节点优先级大为止 ) 这一操作 我们称之为 上浮操作  

下潜

我们删除元素的时候

我们一个一个找,然后删除,最后还有重新排列堆,那样就太繁琐 太麻烦了,我们添加的时候 添加的是优先级最高的,所以删除的时候也可以先删除优先级最高的任务,所以我们可以这样 我们先把 优先级最高的 任务 跟 优先级最低的任务互换,然后从数组的尾部直接删除这个优先级最高的任务,然后以 索引0 为parent节点,找到 他的左右孩子节点,依次跟 左右孩子比较,如果 这个换过来的任务,也就是优先级比较低的任务 比左右孩子中的一个小,就把parent节点更新成左右孩子的其中一个,然后交换二者的任务,然后再根据 新的 parent 找到新的child 进行比较交换 ,知道父亲的优先级 大于 左右孩子或者 左右孩子的索引要数组越界了再停止比较

(翻译过来就是  索引0 节点 跟索引1 2 节点比较优先级 ,如果 索引1节点优先级 比 索引0 大,九把二者的 任务互换,然后以索引1为新的parent节点,索引3  4 为新的左右孩子节点,继续比较优先级) 这一操作称之为 下潜   

代码实现

任务实体类
public class TaskEntry <T>{
    T Task;
    Integer Priority;
    public TaskEntry(T task, Integer priority) {
        Task = task;
        Priority = priority;
    }

    @Override
    public String toString() {
        return "TaskEntry{" +
                "Task=" + Task +
                ", Priority=" + Priority +
                '}';
    }
}
代码实现
public class BigHeap {

    private TaskEntry[] arr;

    /**
     * 记录 堆的元素个数
     */
    private int size;
    //初始化 堆的大小
    private int capacity;

    public BigHeap(int capacity) {
        this.capacity = capacity;
        arr = new TaskEntry[capacity];
    }

    public Boolean isFull() {
        return size == capacity;
    }

    /**
     * @return {@code Boolean }
     */
    public Boolean isEmpty() {
        return size == 0;
    }

    /**
     * 孩子= 应该添加到的数组的索引位置 也就是size
     * 父亲=(孩子-1)/2
     *
     * @param entry
     */
    public void add(TaskEntry entry) {
        if (isFull()) {
            return;
        }
        int child = size;
        int parent = (child - 1) / 2;
        while (child != 0 && entry.Priority > arr[parent].Priority) {
            arr[child] = arr[parent];
            child = parent;
            parent = (child - 1) / 2;
        }
        arr[child] = entry;
        size++;
    }

    public void delete() {
        swap(0, --size);
        arr[size] = null;
        down(0);
    }

    private void down(int parent) {
        int max = parent;
        int left = parent * 2 + 1;
        int right = left + 1;
        while (true){
            if (left < size && arr[left].Priority > arr[parent].Priority) {
                max = left;
            }
            if (right < size && arr[right].Priority > arr[parent].Priority) {
                max = right;
            }
            if (max == parent) {
               break;
            }
            swap(parent,max);
            parent=max;
            left = parent * 2 + 1;
            right = left + 1;
        }
    }

    private void swap(int i, int j) {
        TaskEntry taskEntry = arr[i];
        arr[i] = arr[j];
        arr[j] = taskEntry;
    }
    public  void loop(){
        for (TaskEntry taskEntry : arr) {
            System.out.println(taskEntry);
        }

    }}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis-Plus分页插件注意事项

使用Mybatis-Plus的分页插件进行分页查询时&#xff0c;如果结果需要使用<collection>进行映射&#xff0c;只能使用嵌套查询&#xff0c;而不能使用嵌套结果映射 嵌套查询和嵌套结果映射是Collection映射的两种方式&#xff0c;下面通过一个案例进行介绍 例如有room_i…

MyBatis源码系列3(解析配置文件,创建SqlSessionFactory对象)

创建SqlSessionFactory&#xff1b; 首先读取配置文件&#xff0c;使用构造者模式创建SqlSessionFactory对象。 InputStream inputStream Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder…

C++面试基础系列-struct

系列文章目录 文章目录 系列文章目录C面试基础系列-struct1.C中struct2.C中struct2.1.同名函数2.2.typedef定义结构体别名2.3.继承 3.总结3.1.C和C中的Struct区别 4.struct字节对齐5.struct与const 关于作者 C面试基础系列-struct 1.C中struct struct里面只能放数据类型&#…

算法力扣刷题记录 八十六【47.全排列 II】

前言 回溯章节第12篇。 记录 八十四【46.全排列】初步学习了集合中无重复元素的排列求解。 本文&#xff1a;记录 八十六【47.全排列 II】当集合中有重复元素时&#xff0c;求解排列&#xff1b; 一、题目阅读 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回…

VirtualBox安装Oracle Linux 7.9全流程

1.准备工作 1.1 VirtualBox下载 下载地址1&#xff1a; Downloads – Oracle VM VirtualBoxhttps://www.virtualbox.org/wiki/Downloads 下载地址2&#xff1a; https://www.oracle.com/virtualization/virtualbox/ 选择以上的任意一个地址都可下载到。 1.2 Oracle Linux 操作…

购物车系统设计方案

背景 在电商领域&#xff0c;购物车&#xff08;Shopping Cart&#xff09;扮演着至关重要的角色&#xff0c;它是连接用户浏览商品与最终完成购买行为的桥梁。 从两个视角来阐述&#xff0c;作为ToC的购物车&#xff0c;存在的意义&#xff1a; 从用户角度&#xff1a; 收…

ssm大学生实习管理系统的设计与实现-计算机毕业设计源码45837

摘 要 在信息时代&#xff0c;随着网络的快速发展&#xff0c;各个行业都离不开信息的处理。在这样的背景下&#xff0c;高校需要以学生管理信息为导向&#xff0c;并与学生实习的持续创新相结合。因此&#xff0c;设计一个高校学生实习管理系统就显得非常必要。 该系统采用了B…

维基百科向量搜索;简单易用的GraphRAG实现;友好的人工智能助手;AI的音乐多模态

✨ 1: Semantic Search on Wikipedia 维基百科向量搜索 为了证明 Upstash Vector 的可扩展性&#xff0c;Upstash在一个数据库中以 11 种语言&#xff08;144m 向量&#xff09;索引了整个维基百科 ◆ 超过700GB的数据 ◆ 快速语义搜索 ◆ 与维基百科聊天 为您提供了一款可…

Unity--AssetBundle AB包管理器

1.简介 AB包&#xff08;AssetBundle&#xff09;是Unity中用于资源管理的一种机制&#xff0c;它允许开发者将多个文件&#xff08;如纹理、模型、音频等&#xff09;打包成一个单独的文件&#xff0c;以便于在游戏运行时动态加载和卸载。 但是现在出现了最新的Addressable来…

Python匿名函数之lambda表达式使用详解

概要 在Python编程中,函数是组织代码和实现逻辑的基础单元。除了使用def关键字定义命名函数外,Python还提供了创建匿名函数的方式,即lambda表达式。lambda表达式是一种简洁的函数定义方式,通常用于需要简短函数的场景。本文将详细介绍Python匿名函数的概念、使用场景及其高…

基于51单片机的双机通信控制系统proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1Y4wOJKOYf2E4JeEktyKdTw 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

微分方程(Blanchard Differential Equations 4th)中文版Section3.1

3.1 PROPERTIES OF LINEAR SYSTEMS AND THE LINEARITY PRINCIPLE(线性系统问题与线性算子原理) 在第2章中,我们专注于研究微分方程组的定性和数值方法。之所以这样做,是因为我们很少能找到具有两个或更多个因变量的系统的明确解公式。唯一的例外是线性系统。在本章中,我们…

Linux·权限与工具-yum与vim

1. Linux软件包管理器 yum 1.1 什么是软件包 在Linux下安装软件&#xff0c;一个通常的办法是下载到程序的源代码&#xff0c;并进行编译&#xff0c;得到可执行程序。但这样做太麻烦了&#xff0c;于是有些人把一些常用的软件提前编译好&#xff0c;做成软件包(可以理解成Win…

12.2 使用prometheus-sdk向pushgateway打点

本节重点介绍 : 使用golang sdk打prometheus4种指标&#xff0c;推送到pushgateway gauge、counter、histogram、summary的初始化4种类似的设置值的方法推送到pushgateway的方法 prometheus配置采集pushgateway&#xff0c;grafana上配大盘 golang-sdk 项目地址 https://git…

【图数据库系列】Cypher查询语句:常用语法指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

HTML常用标签和CSS的运用,以及使用HTML做一个简历

目录 1.HTML标签 1.1 文档结构标签 1.2 文本格式标签 1.3 列表标签 1.4 链接和媒体标签 1.5 表格标签 1.6 表单标签 1.7 分区和布局标签 1.8 元数据标签 2.css样式 2.1 字体样式 2.2 文本样式 2.3 背景样式 2.4 边框样式 2.5 间距样式 2.6 宽度和高度 2.7 显示…

三种简单排序:插入排序、冒泡排序与选择排序 【算法 05】

三种简单排序&#xff1a;插入排序、冒泡排序与选择排序 在编程中&#xff0c;排序算法是基础且重要的知识点。虽然在实际开发中&#xff0c;我们可能会直接使用标准库中的排序函数&#xff08;如C的std::sort&#xff09;&#xff0c;但了解并实现这些基础排序算法对于理解算法…

JS编程中有哪些常见的编程“套路”或习惯

JS编程中有哪些常见的编程“套路”或习惯 从个人的编程经验来看&#xff0c;不管你是前端JS编程还是后端Java编程&#xff0c;在一些习惯上基本是通用的。就是你编写的JS代码必须要功能完善且易于阅读易于维护。那么这里整理一下JS编程过程中一些比较行之有效的编程习惯。 函数…

3.Default Constructor的构造操作

目录 1. 问题引入 2. 4种implicitly声明的default constructor 1. 问题引入 “default constructors......在需要的时候被编译产生出来”。关键词是“在需要的时候”&#xff0c;被谁需要&#xff0c;做什么事情&#xff1f;看看下面的代码&#xff0c;然后梳理下思路。 cl…

章二十、Servlet ——

一、 web开发概述 所谓web开发,指的是从网页中向后端程序发送请求,与后端程序进行交互&#xff0c;流程如下&#xff1a; ● 什么是服务器&#xff1f; Web服务器是指驻留于因特网上某种类型计算机的程序&#xff0c;它可以向浏览器等Web客户端提供文档&#xff0c;也可以放置…