首页 > 其他分享 >优先队列(Priority Queue)

优先队列(Priority Queue)

时间:2023-09-04 23:34:28浏览次数:29  
标签:Queue temp 队列 queue Priority int 二叉树 节点

  优先队列是特殊的“队列”,取出元素的顺序是依据优先权(关键字)的大小,而不是依据进入队列的先后顺序。

  对于实现优先队列的存储,数组的插入操作效率比较低,我们考虑使用树。首先想到了二叉树,但多次的删除最值操作可能导致树的不平衡,也会导致效率变低,而完全二叉树平衡性好,并且存储方便,我们可以使用完全二叉树来存储。这里引入堆(Heap)的概念:

  堆(Heap):堆是一颗具有特定性质的二叉树,堆的基本要求就是堆中所有结点的值必须大于或等于(或小于或等于)其孩子结点的值,这也称为堆的性质;堆还有另一个性质,就是当 h > 0 时,所有叶子结点都处于第 h 或 h - 1 层(其中 h 为树的高度),也就是说,堆应该是一颗完全二叉树;

  我们可以用堆来实现优先队列。

  优先队列的完全二叉树表示中有以下特性:

  1.用数组表示完全二叉树,对于存储在a[ i ]中的节点,其左儿子a[ 2*i ],右儿子a[ 2*i+1 ],父节点a[ i/2 ]  ;

  2.任一结点是其子树所有结点关键字的最大值(最小值同理)。

一、插入

  首先将待插入结点放在数组最后,即作为最后一个树的叶子节点,再不断调整至合适位置。操作为:与父节点比较大小,如果大于父节点,则将父节点移到当前位置,待插入节点的位置坐标更新;如果比父节点小,则当前位置就是合适的位置。

 1 const int MAX=1e5;
 2 int size=1;
 3 int queue[MAX];
 4 
 5 void insert(int x)
 6 {
 7     if(size==MAX-1) return;
 8     queue[++size]=x;
 9     int temp=size;
10     for( ;temp>1&&queue[temp/2]<x ; temp/=2)
11     {
12         queue[temp]=queue[temp/2];
13     }
14     queue[temp]=x;
15 }

二、删除

  根节点就是最值,删除时返回根节点,将最后一个叶子节点放置根节点位置,再进行位置调整。操作为:当前待调整位置的节点与左右儿子中的最大值进行比较,如果比这个最大值小,则将较大节点与父节点进行交换;如果大于这个最值,则不再需要调整。

 1 int delete_()
 2 {
 3     int max=queue[1];
 4     int x=queue[size--];
 5     int temp=1;
 6     for( ;temp*2<=size; temp*=2)
 7     {
 8         int big=temp*2;
 9         if( temp*2<size && queue[big+1]>queue[big] ) big++;
10 
11         if( queue[big]<x ) break;
12         else
13         {
14             queue[temp]=queue[big];
15         }
16     }
17     queue[temp]=x;
    return max; 18 }

三、创建堆

  即考虑如何将N个数放在堆中。首先我们想到将元素不断插入到初始为空堆里的方法,这样的时间复杂度为O(nlogn)。其实还有更快的时间复杂度为O(n)的方法,步骤为:

   1.顺序读入N个数,将其存放在数组里,满足完全二叉树的结构

   2.从下往上调整,建立堆

  一个堆的根节点的左子树和右子树一定是堆,而最小的堆是只有一个节点的叶子节点,于是我们可以从叶子节点的父节点开始调整建堆。

 1 void down(int p)
 2 {
 3     int x=queue[p];
 4     int temp=p;
 5     for( ;temp*2<=size; temp*=2)
 6     {
 7         int big=temp*2;
 8         if( temp*2<size && queue[big+1]>queue[big] ) big++;
 9 
10         if( queue[big]<x ) break;
11         else
12         {
13             queue[temp]=queue[big];
14         }
15     }
16     queue[temp]=x;
17 }
18 void creat(int n)
19 {
20     for(int i=1;i<=n;i++) cin>>queue[i];
21     size=n;
22     for(int j=n/2;j>0;j--)
23     {
24         down(j);
25     }
26 }

 

 

  

标签:Queue,temp,队列,queue,Priority,int,二叉树,节点
From: https://www.cnblogs.com/ajn-zuiniu/p/17676418.html

相关文章

  • Java中实现的栈or队列两种方式对比
    Java中实现的栈or队列两种方式对比​ 我们知道,在Java中,可以直接使用Stack来实现栈,这是一种看到名字就会自动想到栈的类,但是现代Java编程中却不推荐使用Stack来实现栈,这是为什么?首先来看一下Java中的Collection接口继承图:Stack1.线程安全,但是带来的开销大,效率低​ Stack是直接......
  • AQS(AbstractQueuedSynchronizer)
    【Mic】AQS的实现原理面试必问的AQS(AbstractQueuedSynchronizer),一文全搞定(qq.com)AQS原理(口语回答)AQS(AbstractQueuedSynchronizer)是JUC下非常核心的一个抽象类,为多线程访问同步资源提供了一个队列同步器。在JUC包下,很多组件都依赖AQS实现线程的同步和唤醒,比如Lock、Semaphor......
  • 云消息队列 RocketMQ 版
    云消息队列RocketMQ版(原ONS)是阿里云基于ApacheRocketMQ构建的低延迟、高并发、高可用、高可靠的分布式“消息、事件、流”统一处理平台。RocketMQ自诞生以来一直服务阿里集团13年,历经多次双十一万亿级数据洪峰稳定性验证。......
  • 云消息队列 RocketMQ 版
    云消息队列RocketMQ版(原ONS)是阿里云基于ApacheRocketMQ构建的低延迟、高并发、高可用、高可靠的分布式“消息、事件、流”统一处理平台。RocketMQ自诞生以来一直服务阿里集团13年,历经多次双十一万亿级数据洪峰稳定性验证。......
  • 剑指 Offer 59 - II. 队列的最大值
    剑指Offer59-II.队列的最大值就是题目剑指Offer59-I.滑动窗口的最大值需要实现的数据结构。一个队列用于正常加入和删除数据,另一个队列用于维护最大值。classMaxQueue{Deque<Integer>q=newArrayDeque<>();Deque<Integer>q_max=newArrayDeque<>();......
  • Enqueue是什么意思?
    加入队列。反义词:dequeue。>>相关:Traversal(遍历):https://www.cnblogs.com/2008nmj/p/17379314.html代码示例://Enqueuetheroottilesthatarerenderableandvisible.for(i=0,len=levelZeroTiles.length;i<len;++i){tile=le......
  • rabbitmq延迟队列
    概念所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费使用场景1、订单在十分钟之内未支付则自动取消2、预定会议后,需要在预定时间点前十分钟通知各个与会人员参加会议。3、淘宝七天自动确认收货,自动评价功......
  • 队列——链式存储
    #include<stdio.h>#include<stdlib.h>//定义typedefstructLinkNode{intdata;structLinkNode*next;}LinkNode;typedefstruct{LinkNode*rear,*front;}LinkQueue;//初始化——带头结点voidInitQueue(LinkQueue&Q){Q.front=Q.rear=......
  • 队列——顺序存储
    #include<stdio.h>#defineMaxSize10//定义typedefstruct{intdata[MaxSize];intrear,front;//队尾指针rear指向队尾元素的下一个位置,队头指针front指向对头元素}SqQueue;//初始化voidInitQueue(SqQueue&Q){Q.front=Q.rear=0;}//判断队空b......
  • rabbitmq死信队列
    死信的概念死信队列(DeadLetterQueue)是指当消息无法被消费者正常消费时,将这些无法消费的消息发送到专门的死信队列中,以便进行进一步的处理。这种处理方式通常被称为“死信处理”。应用场景:为了保证订单业务的消息数据不丢失,需要使用到RabbitMQ的死信队列机制,当消息消费发生......