C++中的优先队列(priority_queue)

什么是优先队列

优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有优先级最高先出的性质。通常采用堆数据结构来实现。

优先队列的原理

std::priority_queue在优先队列中,优先级高的元素先出队列,并非按照先进先出的要求,类似一个堆heap。其模板声明带有三个参数,priority_queue<Type, Container, Functional>, 其中Type为数据类型,Container为保存数据的容器,Functional为元素比较方式。Container必须是用数组实现的容器,比如 vector, deque. STL里面默认用的是vector. 比较方式默认用operator< , 所以如果把后面两个参数缺省的话,优先队列就是大顶堆队头元素最大

优先队列常常用堆heap来实现。是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置i的节点的父节点位置一定为 i/2,而它的两个子节点的位置
又一定分别为 2i+12i+2

以下是堆的实现方法,其中最核心的两个操作是 上浮 swim下沉sink:如果一个节点比父节点大,那么需要交换这个两个节点;交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,我们称之为上浮;类似地,如果一个节点比父节小,也需要不断地向下进行比较和交换操作,我们称之为下沉。如果一个节点有两个子节点,我们总是交换最大的子节点。

如何定义

priority_queue<>尖括号里写数据类型容器名称排列规则

  • 数据类型可以是int char double string等等
  • 容器名称一般使用vector动态数组
  • 排列规则一般是大根堆或者小根堆,表示最大最小的优先级别最高

但有一种特殊情况,数据类型为结构体时,第二个和第三个都可省略,容器名称默认是vector(关于可变长数组可看本人创作的C++中的可变长数组(vector),每个成员都是结构体,排列规则是根据某一个元素的大小进行排序,就和sort(关于快速排列可看本人创作的C++中的快速排列(sort))里的cmp是一个道理,优先队列排列规则默认为operator<但是注意,在operator<里的比较规则和cmp恰恰相反!比如在cmp里,a.x>b.x表示按x的降序排列,但在operator<里则是升序排;同样的greatercmp里表示表示升序,然而在operator<里则代表降序。
举个例子:

#include<bits/stdc++.h>
using namespace std;
struct node
{
   int id,shu,yu;
};
bool operator<(node a,node b)
{
   return a.shu>b.shu;
}
int main()
{
   priority_queue<node>q;
   int i,n,a,b,c;
   cin>>n;
   for(i=1;i<=n;i++)
   {
   	cin>>a>>b>>c;
   	q.push({a,b,c});
   	
   }
   while(!q.empty())
   {
   	cout<<q.top().id<<" "<<q.top().shu<<" "<<q.top().yu<<endl;
   	q.pop();
   }
   return 0;
}

这里注意一点:如果第三项的排列规则没有省略,后面的尖括号与优先队列的尖括号之间一定要有空格,否则电脑会把它识别为右移运算符,会报错:

	priority_queue<int,vector<int>,less<int> >q;

常用的函数:

empty();

用来判断这个队列是否为空,不为空返回假,否则返回真

pop();

将优先级最高的元素删除

push();

队尾插入一个元素,如果要插多个,要打{}

size();

返回元素的个数

top()

返回队首元素
今天就讲这么多关于优先队列的内容,如果有不懂的问题,欢迎留在评论区哦

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值