优先级队列的模拟实现

news2024/11/16 21:40:55

目录

1. 优先级队列的概念

1.1堆的概念

1.2堆的性质

 1.3堆的存储方式

2. 堆的创建

2.1堆的创建代码解析

 2.2建堆的时间复杂度

 2.3堆的插入

2.4 堆的删除

2.5常见习题


1. 优先级队列的概念

队列是一种先进先出 (FIFO) 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可能需要优先级高的元素先出队列 在这种情况下, 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象 。这种数 据结构就是 优先级队列 (Priority Queue)

1.1堆的概念

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

以大根堆为例:

1.2堆的性质

  • 堆中某个节点的值总是不大于或不小于其父节点的值;

  • 堆总是一棵完全二叉树。

 1.3堆的存储方式

从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储

注意: 对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节 点,就会导致空间利用率比较低
将元素存储到数组中后, 假设 i 为节点在数组中的下标,则有:
如果 i 0 ,则 i 表示的节点为根节点,否则 i 节点的双亲节点为 (i - 1)/2
如果 2 * i + 1 小于节点个数,则节点 i 的左孩子下标为 2 * i + 1 ,否则没有左孩子
如果 2 * i + 2 小于节点个数,则节点 i 的右孩子下标为 2 * i + 2 ,否则没有右孩子

2. 堆的创建

public class TextHeap {
    public int[] arr;
    public int size;

    public TextHeap(int[] arr) {
        this.arr = arr;
        size=arr.length;
    }
    public void createheap(){
        for (int parent = (size-1-1)/2; parent >=0 ; parent--) {
           shiftDown(parent,size);
        }
    }

    private void shiftDown(int parent,int len){
        int child=2*parent+1;
        while(child<len){
            if(child+1<len&&arr[child+1]>arr[child]){
                child++;
            }
            if(arr[parent]<arr[child]){
                int tmp=arr[parent];
                arr[parent]=arr[child];
                arr[child]=tmp;
                parent=child;
                child=2*parent+1;
            }else {
                break;
            }
        }
    }
}

2.1堆的创建代码解析

向下过程(以大根堆为例):

  1. 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)
  2. 如果parent的左孩子存在,即:child < size, 进行以下操作,直到parent的左孩子不存在
  3. parent右孩子是否存在,存在找到左右孩子中最大的孩子,让child进行标将parent与较大的孩子child比较。

    如果parent大于较大的孩子child,调整结束。
    否则:交换parent与较大的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子树不满足对的性质,因此需要继续向下调整即parent = child;child = parent*2+1; 然后继续(2)。

 2.2建堆的时间复杂度

 2.3堆的插入

堆的插入总共需要两个步骤:
1. 先将元素放入到底层空间中 ( 注意:空间不够时需要扩容 )。
2. 将最后新插入的节点向上调整,直到满足堆的性质。
代码:
    public void shiftUp(int child){
        int parent=(child-1)/2;
        while(child>0){
            if(arr[child]>arr[parent]){
                int tmp = arr[parent];
                arr[parent] = arr[child];
                arr[child] = tmp;
                child=parent;
                parent=(child-1)/2;
            }else {
                break;
            }
        }
    }

    public void offer(int val) {
        if (isfull()) {
            arr = Arrays.copyOf(arr, arr.length * 2);
        }
        arr[size++] = val;

    }

    public boolean isfull() {
        return arr.length == size;
    }

从0开始插入建堆的时间复杂度

2.4 堆的删除

注意:堆的删除一定删除的是堆顶元素。 具体如下:
1. 将堆顶元素对堆中最后一个元素交换
2. 将堆中有效数据个数减少一个
3. 对堆顶元素进行向下调整
代码:
    public boolean empty() {
        return 0 == size;
    }
    public void pop(){
        if (empty()){
            return;
        }
        int tmp = arr[0];
        arr[0] = arr[size-1];
        arr[size-1] = tmp;
        size--;
        shiftDown(0,size);
    }

2.5常见习题

1. 下列关键字序列为堆的是 :()
A: 100,60,70,50,32,65                B: 60,70,65,50,32,100               C: 65,100,70,32,50,60
D: 70,65,100,32,50,60                E: 32,50,100,70,65,60               F: 50,100,70,65,60,32
解析:
答案:A
B为啥错如下,其他同理。
2. 已知小根堆为 8,15,10,21,34,16,12 ,删除关键字 8 之后需重建堆,在此过程中,关键字之间的比较次数是 ()
A: 1            B: 2             C: 3           D: 4
解析:
答案:C

 3.最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是()

A: [3 2 5 7 4 6 8]                         B: [2 3 5 7 4 6 8]
C: [2 3 4 5 7 8 6]                         D: [2 3 4 5 6 7 8]
解析:
答案:C

以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

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

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

相关文章

Allegro174版本如何关闭模块复用后铜皮自动从动态变成静态操作指导

Allegro174版本如何关闭模块复用后铜皮自动从动态变成静态操作指导 在用Allegro进行PCB设计的时候,模块复用是使用的十分频繁的操作,当Allegro升级到了174 S034版本的时候,当使用模块复用的功能的时候,模块内的铜皮会自动动静转换,大部分情况是不需要的。 如下图 如何关闭…

【再识C进阶4】详细介绍自定义类型——结构体、枚举和联合

学习目标&#xff1a; 在上一篇博客中&#xff0c;我们已经详细地学习了字符分类函数、字符转换函数和内存函数。那这一篇博客和上一篇博客的关系不是那么相连。 这一篇博客主要介绍一下自定义类型&#xff0c;因为在解决实际问题时&#xff0c;由于世界上的因素有很多&#xf…

01.爬虫基础

1、Python爬虫介绍 爬虫的实战性要求很强。爬虫经常需要爬取商业网站或政府网站的内容&#xff0c;而这些网站随时可能进行更新&#xff0c;另外网络原因和网站反爬虫机制也会对爬虫代码演示造成干扰。 1、1 爬虫的用处 网络爬虫&#xff1a;按照一定的规则&#xff0c;自动…

【Java 进阶篇】JDBC 管理事务详解

在数据库操作中&#xff0c;事务是一个非常重要的概念。事务可以确保一系列的数据库操作要么全部成功执行&#xff0c;要么全部失败回滚&#xff0c;以保持数据库的一致性和完整性。在 Java 中&#xff0c;我们可以使用 JDBC 来管理事务。本文将详细介绍 JDBC 管理事务的方法和…

【Java 进阶篇】JDBC 数据库连接池详解

数据库连接池是数据库连接的管理和复用工具&#xff0c;它可以有效地降低数据库连接和断开连接的开销&#xff0c;提高了数据库访问的性能和效率。在 Java 中&#xff0c;JDBC 数据库连接池是一个常见的实现方式&#xff0c;本文将详细介绍 JDBC 数据库连接池的使用和原理。 1…

vs2015 函数声明、定义与引用

10.VS-函数声明、定义和引用 - 简书 简言之&#xff0c;函数先在头文件中被声明&#xff0c;然后在对应cpp文件中实现&#xff08;定义&#xff09;&#xff0c;最后被不同文件的代码调用&#xff08;引用&#xff09;。

集合原理简记

HashMap 无论在构造函数是否指定数组长度&#xff0c;进行的都是延迟初始化 构造函数作用&#xff1a; 阈值&#xff1a;threshold&#xff0c;每次<<1 &#xff0c;数组长度 负载因子 无参构造&#xff1a;设置默认的负载因子 有参&#xff1a;可以指定初始容量或…

ES6中对象的扩展

1. 属性的简洁表示法 可以直接写入变量和函数作为对象的属性和方法。在对象中只写属性名&#xff0c;不写属性值&#xff0c;代表属性值等于和属性名相同的的变量的值。 属性的简写 let foo bar; let baz {foo}; // { foo: bar } // 等同于 let baz { foo: foo}方法的简写…

力扣 -- 377. 组合总和 Ⅳ

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int combinationSum4(vector<int>& nums, int target) {int nnums.size();vector<double> dp(target1);//初始化dp[0]1;//填表for(int i1;i<target;i){for(int j0;j<n;j){//填表if(…

Windows下启动freeRDP并自适应远端桌面大小

几个二进制文件 xfreerdp # Linux下的&#xff0c;an X11 Remote Desktop Protocol (RDP) client which is part of the FreeRDP project wfreerdp.exe # Windows下的&#xff0c;freerdp2.0 主程序&#xff0c;freerdp3.0将废弃 sdl-freerdp.exe # Windows下的&…

Linux系统及Docker安装RabbitMq

目录 一、linux系统安装 1、上传文件 2、在线安装依赖环境 3、安装Erlang 4、安装RabbitMQ 5、开启管理界面及配置 6、启动 7、删除mq 二、docker安装 1、上传mq.tar包或使用命令拉取镜像 2、启动并运行 3、访问mq 一、linux系统安装 1、上传文件 2、在线安装依赖环…

B2主题优化:WordPress文章每次访问随机增加访问量

老站长都知道&#xff0c;一个新站刚开始创建&#xff0c;内容也不多的时候&#xff0c;用户进来看到文章浏览量要么是0&#xff0c;要么是 个位数&#xff0c;非常影响体验&#xff0c;就会有一种“这个网站没人气&#xff0c;看来不行”的感觉。 即使你的内容做的很好&#x…

5.Vectors Transformation Rules

在上节&#xff0c;有个问题&#xff1a;向量分量的转换方式 与 新旧基底的转换方式相反 用例子来感受一下&#xff0c; 空间中一向量V&#xff0c;即该空间的一个基底&#xff1a;e1、e2 v e1 e2 现把基底 e1 、 e2 放大两倍。变成 基向量放大了两倍&#xff0c; 但对于…

Day-05 CentOS7.5 安装docker

参考 &#xff1a; Install Docker Engine on CentOS | Docker DocsLearn how to install Docker Engine on CentOS. These instructions cover the different installation methods, how to uninstall, and next steps.https://docs.docker.com/engine/install/centos/ Doc…

「专题速递」RTC云网端联合优化、弱网对抗策略、QUIC协议的能力和实践

随着互联网日益增长的加速需求、复杂的网络环境和多样化的视频业务&#xff0c;音视频技术领域的专家们正在不断探索如何实现准确和极低延迟的网络传输能力。他们在应用层流控、传输层协议设计以及跨层优化等方面积极努力&#xff0c;以改善用户的网络体验。 在当今数字化时代&…

Spacewalk

Spacewalk Spacewalk是一种开源的系统管理工具&#xff0c;提供了集中管理多个Linux服务器的功能。以下是一些Spacewalk用例&#xff1a; Spacewalk是基于Substrate的parachains和Stellar之间的桥梁&#xff0c;可以实现与Stellar的资产转移。该拨款申请用于开发太空行走协议…

Java 基于 SpringBoot 的学生考勤系统

1 简介 本文讲解的是 Java基于 SpringBoot 的学生考勤系统。学生考勤管理系统能做到的不仅是大大简化管理员的信息管理工作&#xff0c;在提高学生考勤管理效率的同时还能缩减开支&#xff0c;更能在数字化的平面网络上将学生考勤管理最好的一面展示给客户和潜在客户&#xff…

MyBatisCodeHelper Pro3.x新版本插件自由

1效果图 我的版本为3.2.2 2.资源链接 码云地址点这里 3.使用说明 将我修改好后的MyBatisCodeHelper-Pro-obfuss.jar替换MybatisCodeHelperNew-3.x.x.zip&#xff08;原版本插件&#xff09;\MyBatisCodeHelper-Pro\lib中的MyBatisCodeHelper-Pro-obfuss.jar 4.实现与感谢…

腾讯云南京服务器性能如何?南京服务器测速IP地址

腾讯云服务器南京地域怎么样&#xff1f;南京地域很不错&#xff0c;正好处于中间的位置&#xff0c;南方北方用户均可以选择&#xff0c;网络延迟更低速度更快&#xff0c;并且目前南京地域有活动&#xff0c;南京地域可用区可选南京一区、南京二区和南京三区&#xff0c;腾讯…

c语言实现玫瑰花

浅浅跟波风 1.效果图 2.代码实现 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h>const int max_iterations 128; const float stop_threshold 0.01f; const float grad_step 0.01f; const float clip_far 10.0f;const float PI 3.1…