C++优先队列用法案例详解
作者:华山青竹 发布时间:2022-10-23 17:35:01
标签:C++,优先队列
c++优先队列(priority_queue)用法详解
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。
首先要包含头文件#include<queue>, 他和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队。
优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。
和队列基本操作相同:
top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容
定义:priority_queue<Type, Container, Functional>
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式。
当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆。
一般是:
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,大顶堆
priority_queue <int,vector<int>,less<int> >q;
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
1、基本类型优先队列的例子:
#include<iostream>
#include <queue>
using namespace std;
int main()
{
//对于基础类型 默认是大顶堆
priority_queue<int> a;
//等同于 priority_queue<int, vector<int>, less<int> > a;
// 这里一定要有空格,不然成了右移运算符↓↓
priority_queue<int, vector<int>, greater<int> > c; //这样就是小顶堆
priority_queue<string> b;
for (int i = 0; i < 5; i++)
{
a.push(i);
c.push(i);
}
while (!a.empty())
{
cout << a.top() << ' ';
a.pop();
}
cout << endl;
while (!c.empty())
{
cout << c.top() << ' ';
c.pop();
}
cout << endl;
b.push("abc");
b.push("abcd");
b.push("cbd");
while (!b.empty())
{
cout << b.top() << ' ';
b.pop();
}
cout << endl;
return 0;
}
运行结果:
4 3 2 1 0
0 1 2 3 4
cbd abcd abc
请按任意键继续. . .
2、用pair做优先队列元素的例子:
规则:pair的比较,先比较第一个元素,第一个相等比较第二个。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
priority_queue<pair<int, int> > a;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty())
{
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
}
运行结果:
2 5
1 3
1 2
请按任意键继续. . .
3、用自定义类型做优先队列元素的例子
#include <iostream>
#include <queue>
using namespace std;
//方法1
struct tmp1 //运算符重载<
{
int x;
tmp1(int a) {x = a;}
bool operator<(const tmp1& a) const
{
return x < a.x; //大顶堆
}
};
//方法2
struct tmp2 //重写仿函数
{
bool operator() (tmp1 a, tmp1 b)
{
return a.x < b.x; //大顶堆
}
};
int main()
{
tmp1 a(1);
tmp1 b(2);
tmp1 c(3);
priority_queue<tmp1> d;
d.push(b);
d.push(c);
d.push(a);
while (!d.empty())
{
cout << d.top().x << '\n';
d.pop();
}
cout << endl;
priority_queue<tmp1, vector<tmp1>, tmp2> f;
f.push(b);
f.push(c);
f.push(a);
while (!f.empty())
{
cout << f.top().x << '\n';
f.pop();
}
}
运行结果:
3
2
1
3
2
1
请按任意键继续. . .
来源:https://www.cnblogs.com/huashanqingzhu/p/11040390.html


猜你喜欢
- 1. this 引用1.1 为什么要有this引用先来写一个日期类的例子:public class classCode { &
- 做消息通信,消息会不断从网络流中取得,而后台也有线程不断消费。本来我一直是使用一些线程安全标识或方法来控制,后来在网上找到一些java新特性
- 学习app对excel的读写控制1.界面设计<?xml version="1.0" encoding="
- hello,我是灰小猿,一个超会写bug的程序员!近期在写一个spring cloud Alibaba读取Nacos配置中心远程配置文件的内
- 新建一个类MyPageInterceptor.java(注意在springboot中要添加注解@Component)package com.
- Java中对象创建,内存分配,垃圾回收的权力交给了虚拟机,这其中有利也有弊,程序员也减轻了负担,但是如果不熟悉Java的内存区域划分,一旦出
- 简介相信大家有配置过多数据源,或者即将配置多数据的朋友们,会发现网上大概有以下几种方案:1. 使用 AOP 切片进行动态数据源切换2. 使用
- 目录一、Actuator简介二、与SpringBoot2.0整合 1、核心依赖Jar包2、Yml配置文件三、监控接口详解 
- 使用第三方的vitamio插件实现简易的播放器。vitamio版本(5.2.3)官网地址:官网地址效果展示效果项目结构代码:MainActi
- 前言消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题,实现高性能、高可用、可伸缩和最终一致性架构,是大型分
- 前言今天刷个题,遇到一个很有趣的问题,关于Comparator的使用,感觉也是一个关于写代码的一些小细节的问题关于ComparatorCom
- 一、DurationDuration主要用来衡量秒级和纳秒级的时间,使用于时间精度要求比较高的情况。先来看看Duration的定义:publ
- 1. 概述将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。2. 解决的问题当希望忽
- 对列表进行排序也是我们经常遇到的问题,这里缩小一下范围,使用map来对列表排序。相信大家都有过TreeMap排序的经历,不过Map.Entr
- 在eclipse中默认的maven,它加载的是国外的镜像,那样速度会比较慢,如果使用国内镜像,比如阿里的中央仓库;速度会快很多。那如何修改m
- 资源加载器使用Java,您可以使用当前线程的classLoader并尝试加载文件,但是Spring Framework为您提供了更为优雅的解
- 本篇主要是自定义动画与Animatable。AnimationSpec上一篇中,出现了多次animationSpec属性,它是用来自定义动画
- 问题描述使用@Autowired处理多个同种类型的bean,出现@Value和@Bean的执行顺序问题。首先使用扫描包+注解的方式注册Use
- 使用Zenject和UniRx的入门级技术实现了伪登录注册功能。运行效果登录面板using System;using UniRx;using
- 本文实例为大家分享了SSM实现学生管理系统的具体代码,供大家参考,具体内容如下概述基于Spring + Spring MVC 的学生管理系统