【优先级队列】

news2024/11/29 10:43:45

文章目录

  • 基于无序数组实现
  • 基于有序数组的实现
  • 基于堆的实现
  • 合并多个有序链表-力扣 23 题

基于无序数组实现

要点

  1. 入队保持顺序,在数组尾部插入即可
  2. 出队前找到优先级最高的出队,相当于一次选择排序

基于有序数组的实现

要点

  1. 入队后排好序,优先级最高的排列在尾部
  2. 出队只需删除尾部元素即可

基于堆的实现

堆是一种基于树的数据结构,通常用完全二叉树实现。堆的特性如下

  • 在大顶堆中,任意节点 C 与它的父节点 P 符合 P . v a l u e ≥ C . v a l u e P.value \geq C.value P.valueC.value
  • 而小顶堆中,任意节点 C 与它的父节点 P 符合 P . v a l u e ≤ C . v a l u e P.value \leq C.value P.valueC.value
  • 最顶层的节点(没有父亲)称之为 root 根节点

完全二叉树可以使用数组来表示:
在这里插入图片描述

特征

  • 如果从索引 0 开始存储节点数据
    • 节点 i i i 的父节点为 f l o o r ( ( i − 1 ) / 2 ) floor((i-1)/2) floor((i1)/2),当 i > 0 i>0 i>0
    • 节点 i i i 的左子节点为 2 i + 1 2i+1 2i+1,右子节点为 2 i + 2 2i+2 2i+2,当然它们得 < s i z e < size <size
  • 如果从索引 1 开始存储节点数据
    • 节点 i i i 的父节点为 f l o o r ( i / 2 ) floor(i/2) floor(i/2),当 i > 1 i > 1 i>1
    • 节点 i i i 的左子节点为 2 i 2i 2i,右子节点为 2 i + 1 2i+1 2i+1,同样得 < s i z e < size <size

用大顶锥实现优先级队列:
入队:将新元素加入队尾,然后不断比较其与父节点的优先级,若大于父节点优先级,则交换两节点,然后再比较新节点的父节点,直到找到小于父节点优先级,或者当前节点(child)索引为0,则找到。

public boolean offer(E offered) {
        if (isFull()) {
            return false;
        }
        int child = size++;//当前child指向数组最后一个元素,然后size++
        int parent = (child - 1) / 2;
        while (child > 0 && offered.priority() > array[parent].priority()) {
            array[child] = array[parent];
            child = parent;
            parent = (child - 1) / 2;
        }
        array[child] = offered;
        return true;
    }

出队:将数组索引为0的元素与数组最后元素交换,交换后数组最后一个元素就是优先级最大的元素,将其出队,然后将数组为0位置元素逐步下潜,调整大顶锥,使其满足大顶锥定义。


    public E poll() {
        if (isEmpty()) {
            return null;
        }
        swap(0, size - 1);
        size--;
        Priority e = array[size];
        array[size] = null;
        
        shiftDown(0);        
        return (E) e;
    }
    

    void shiftDown(int parent) {
        int left = 2 * parent + 1;
        int right = left + 1;
        int max = parent;
        if (left < size && array[left].priority() > array[max].priority()) {
            max = left;
        }
        if (right < size && array[right].priority() > array[max].priority()) {
            max = right;
        }
        if (max != parent) {
            swap(max, parent);
            shiftDown(max);
        }
    }
    private void swap(int i, int j) {
	        Priority t = array[i];
	        array[i] = array[j];
	        array[j] = t;
	}

合并多个有序链表-力扣 23 题

在这里插入图片描述

思路:小顶锥实现,k个链表创建有k个元素的小顶锥,用优先级队列实现(遍历lists,如果遍历到的不是空链表,将头节点加入到优先级队列中,)当队列不空时循环取出元素,取出的这个元素就是最小的元素,并将此元素加入到新的链表中,然后将当前这个最小的元素的next节点入队(当next节点存在的情况下),当优先级队列为空时表示已经将k个链表合并。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        Queue<ListNode> pq = new PriorityQueue<>((v1, v2)-> v1.val - v2.val);
        for(ListNode node : lists){
            if(node != null){
                pq.offer(node);
            }
        }
        ListNode sentinel = new ListNode(-1, null);
        ListNode tail = sentinel;
        while(!pq.isEmpty()){
            ListNode minNode = pq.poll();
            tail.next = minNode;
            tail = minNode;
            if(minNode.next != null){
                pq.offer(minNode.next);
            }
        }
        return sentinel.next;
    }

    
}

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

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

相关文章

企业架构LNMP学习笔记8

1、 运维人员需要考虑安全性、稳定性。 安装&#xff1a; 解压进入到目录&#xff1a; shell > tar zxf php-7.2.12.tar.gz shell > cd php-7.2.12 安装依赖软件&#xff1a; yum -y install libxml2-devel libjpeg-devel libpng-devel freetype-devel curl-devel op…

企业应用系统 PHP项目支持管理系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP 项目支持管理系统是一套完善的web设计系统 应用于企业项目管理&#xff0c;从企业内部的各个业务环境总体掌握&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 php项目支撑管理系统2 二、功能介绍 (1)权限管理&#xff1…

Android 使用OpenCV实现实时人脸识别,并绘制到SurfaceView上

1. 前言 上篇文章 我们已经通过一个简单的例子&#xff0c;在Android Studio中接入了OpenCV。 之前我们也 在Visual Studio上&#xff0c;使用OpenCV实现人脸识别 中实现了人脸识别的效果。 接着&#xff0c;我们就可以将OpenCV的人脸识别效果移植到Android中了。 1.1 环境说…

一个基于YAPI接口生产代码的开源工具

前后端分离的开发模式是一种趋势&#xff0c;但如果缺少好的开发工具跟管理模式&#xff0c;会使得前后端开发人员相互等待&#xff0c;扯皮等问题。从而影响项目的交付进度。 通过实践摸索&#xff0c;YAPI是一款很适合前后端分离开发的协助工具。它以项目为维度&#xff0c;可…

arduino仿真 SimulIDE1.0仿真器

SimulIDE 是一个开源的电子电路模拟器&#xff0c;支持模拟各种电子元器件的行为&#xff0c;可以帮助电子工程师和爱好者进行电路设计和测试。以下是 SimulIDE 的安装和使用说明&#xff1a; 安装 SimulIDE SimulIDE 可以在 Windows、Linux 和 Mac OS X 等操作系统上安装。您…

取证工具prodiscover的基本操作

前言提醒 取证工具ProDiscover在网上讲解操作的文章实在太少&#xff0c;一是prodiscover是用于磁盘取证的工具&#xff0c;本身比较小众比不上其他的编程软件能用到的地方多&#xff0c;二是这个工具是用来恢复提取磁盘中被删除的文件&#xff0c;是比较隐晦的软件。 需要注…

CSAPP的Lab学习——AttackLab

文章目录 前言一、阶段一攻击二、阶段二攻击三、阶段三攻击四、阶段四攻击五、阶段五攻击总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。刚刚看完CSAPP&#xff0c;真是一本神书啊&#xff01;遂尝试将它的Lab实现&#xff0c;并记录期间心酸历程。 代码下载 官方…

【AWS实验】 配置中转网关及对等连接

文章目录 实验概览目标实验环境任务 1&#xff1a;查看网络拓扑并创建基准任务 2&#xff1a;创建中转网关任务 3&#xff1a;创建中转网关挂载任务 4&#xff1a;创建中转网关路由表任务 4.1&#xff1a;创建路由表关联任务 4.2&#xff1a;创建路由传播 任务 5&#xff1a;更…

velodyne_msgs/VelodyneScan数据流消息转化为sensor_msgs/PointCloud2点云帧消息

目的 在查看一个开源数据集时&#xff0c;点云信息格式为velodyne_msgs/VelodyneScan&#xff0c;无法在rviz中显示&#xff0c;需要转换为sensor_msgs/PointCloud2。 软件版本 Ubuntu20.04 Noetic 激光雷达型号 32线激光雷达velodyne 32E 参考方法 ROS Noetic velodyn…

【DP】CF Edu 21 E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 就是一个 N为1e5&#xff0c;M为3e5的背包问题&#xff0c;不过特殊条件是 w < 3 我们去从最简单的情况开始考虑 当只有w 1的物品和w 2的物品时&#xff0c;考虑贪心地把物品按价值排序&#xff0c;然后选…

Python数据分析实战-判断一组序列(列表)的变化趋势(附源码和实现效果)

实现功能 判断一组序列&#xff08;列表&#xff09;的变化趋势 实现代码 from sklearn.linear_model import LinearRegression import numpy as np # 计算相邻两个数之间的差值的均值&#xff0c;并判断变化趋势。 def trend(lst):diff [lst[i1] - lst[i] for i in range(…

Python之循环-三元表达式

Python之循环-三元表达式 continue, break break 结束循环 break语句可以提前结束循环。然后执行循环之后的语句。 continue continue用于跳出当前循环&#xff0c;执行下一次循环。 示例&#xff1a; 如下示例中是一个for循环&#xff0c;range(10)&#xff0c;然后遍历r…

【高效编程技巧】编程菜鸟和编程大佬的差距究竟在哪里?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《高效编程技巧》《C语言进阶》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言1.如何写出好的代码&#xff1f;1.2 如何分析一个函数写的怎么样 2. 代码板式的重要性2.1 代码…

【C++】学习STL中的stack和queue

❤️前言 今天这篇博客的内容主要关于STL中的stack、queue和priority_queue三种容器。 正文 stack和queue的使用方式非常简单&#xff0c;我们只要根据之前学习数据结构的经验和文档介绍就可以轻松上手。于是我们直接开始对它们的模拟实现。 stack和queue的模拟实现 stack和q…

redis实战-实现优惠券秒杀解决超卖问题

全局唯一ID 唯一ID的必要性 每个店铺都可以发布优惠券&#xff1a; 当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增ID就存在一些问题&#xff1a; id的规律性太明显&#xff0c;容易被用户根据id的间隔来猜测…

不同路径【动态规划】

不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f;…

python 美国总统身高统计与分析

美国总统身高统计与分析 1.安装依赖2.下载数据集3.数据处理4.结果展示 1.安装依赖 pip install pandas pip install numpy pip install matplotlib2.下载数据集 链接&#xff1a;https://pan.baidu.com/s/1aZLtkLyvQvRLb9tJ-B1krA 提取码&#xff1a;thms –来自百度网盘超级…

Spring Cloud 系列之OpenFeign:(8)链路追踪续

传送门 Spring Cloud Alibaba系列之nacos&#xff1a;(1)安装 Spring Cloud Alibaba系列之nacos&#xff1a;(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos&#xff1a;(3)服务注册发现 Spring Cloud 系列之OpenFeign&#xff1a;(4)集成OpenFeign Spring Cloud …

无涯教程-JavaScript - CUBEMEMBERPROPERTY函数

描述 CUBEMEMBERPROPERTY函数从多维数据集返回成员属性的值。使用此函数可以验证多维数据集中是否存在成员名称,并返回该成员的指定属性。 语法 CUBEMEMBERPROPERTY (connection, member_expression, property)争论 Argument描述Required/OptionalconnectionName of the co…

Glide的使用及源码分析

前言 依赖 implementation com.github.bumptech.glide:glide:4.16.0 github: GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling 基本使用 //加载url Glide.with(this) .load(url) .placeholder(R.drawable.placehol…