C++优先队列_队列queue中添加元素的方法

C++优先队列_队列queue中添加元素的方法1.优先级队列(priority_queue)1.1基本概念之前已经提到了队列(queue),队列是一种先进先出(FirstinFirstout,FIFO)的数据类型。每次元素的入队都只能添加到队列尾部,出队时从队列头部开始出。优先级队列(priority_queue)其实,不满足先进先出的条件,更像是数据类型中的“堆”。优先级队列每次出队的元素是队列中优先级最高的那个元素,而不是队首的元素。这个优先级可以通过元素的大小等进行定义。比如定义元素越大优先级越高,那么每次出队,都是将当前队.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

目录

 

1. 优先级队列(priority_queue)

1.1 基本概念

1.2 优先级队列的定义

1.3 通过重写仿函数来支持自定义数据类型

1.4 通过运算符重载来支持自定义比较函数

1.5 优先级队列的基本操作

2. 示例程序


1. 优先级队列(priority_queue)

1.1 基本概念

之前已经提到了队列(queue)队列是一种先进先出(First in First out,FIFO)的数据类型。每次元素的入队都只能添加到队列尾部出队时从队列头部开始出。

优先级队列(priority_queue)其实,不满足先进先出的条件,更像是数据类型中的“堆”优先级队列每次出队的元素是队列中优先级最高的那个元素,而不是队首的元素。这个优先级可以通过元素的大小等进行定义比如定义元素越大优先级越高,那么每次出队,都是将当前队列中最大的那个元素出队。个人感觉这就是所谓“优先级”的定义。

现在看优先级队列是不是就是“堆”了,如果最大的元素优先级最高,那么每次出队的就是当前队列中最大的元素,那么队列实际就相当于一个大顶堆,每次将堆根节点元素弹出,重新维护大顶堆,就可以实现一个优先级队列。

1.2 优先级队列的定义

C++中,使用优先级队列需要包含头文件<queue>,优先级队列的定义如下:

priority_queue<typename, container, functional>
  • typename是数据的类型;
  • container是容器类型,可以是vector,queue等用数组实现的容器,不能是list,默认可以用vector;
  • functional是比较的方式,默认是大顶堆(就是元素值越大,优先级越高);如果使用C++基本数据类型可以直接使用自带的less和greater这两个仿函数默认使用的是less,就是构造大顶堆,元素小于当前节点时下沉)。使用自定义的数据类型的时候,可以重写比较函数也可以进行运算符重载less重载小于“<”运算符,构造大顶堆greater重载大于“>”运算符,构造小顶堆)。

定义一个优先级队列的示例如下:

//构造一个大顶堆,堆中小于当前节点的元素需要下沉,因此使用less
priority_queue<int, vector<int>, less<int>> priQueMaxFirst;

//构造一个小顶堆,堆中大于当前节点的元素需要下沉,因此使用greater
priority_queue<string, vector<string>, greater<string>> priQueMinFirst;

1.3 通过重写仿函数来支持自定义数据类型

仿函数是通过重载“()”运算符来模拟函数操作的类

先自定义一个类Data,将id作为该类的关键字,进行比较,重写仿函数

//自定义数据类型,Data类
class Data
{
public:
	Data(int i, int d) :id(i), data(d) {}
	~Data() {}
	int getId() { return id; }
	int getData() { return data; }
private:
	int id;
	int data;
};
//重写仿函数,完成less的功能,也可以用class定义类,此时需要将运算符重载函数设为public
//结构体struct中默认是访问类型是public
struct cmp    
{
	bool operator() ( Data &a, Data &b) {
		return a.getId() < b.getId();
	}
};

int main(void){
    priority_queue<Data, vector<Data>, cmp > priQueMaxFirst;//该优先级队列维护一个大顶堆,因此最大的元素最先出队
    ...//一系列操作
    ...
    return 0;
}

1.4 通过运算符重载来支持自定义比较函数

运算符重载的话,由于是重载双目运算符,因此需要使用友元函数,我们在类内声明友元函数,在类外实现友元函数,如下:

//自定义数据类型,Data类
class Data
{
public:
	Data(int i, int d) :id(i), data(d) {}
	~Data() {}
	int getId() { return id; }
	int getData() { return data; }
	friend bool operator < (const Data &a, const Data &b);//运算符重载,友元函数可以访问类的私有成员
private:
	int id;
	int data;
};
//重载“<”运算符,仿函数less中需要使用
bool operator < (const Data &a, const Data &b) {
	return a.id < b.id;
}

int main(void){
    priority_queue<Data, vector<Data>, less<Data> > priQueMaxFirst;//该优先级队列维护一个大顶堆,因此最大的元素最先出队
    ...//一系列操作
    ...
    return 0;
}

1.5 优先级队列的基本操作

优先级队列的基本操作与普通队列类似,不同的是每次获得队内的元素是优先级最高的元素(要从堆的顶部开始),因此使用的是top()方法,而不是front()方法。如下:

  1. push() :入队。向队列添加一个元素,无返回值;
  2. pop() :将队列中优先级最高的元素出队。将队列中优先级最高的元素删除(出队),无返回值;
  3. top() :获得队列优先级最高的元素。此函数返回值为队列中优先级最高的元素,常与pop()函数一起,先通过top()获得队列中优先级最高的元素,然后将其从队列中删除;
  4. size() :获得队列大小。此函数返回队列的大小,返回值是“size_t”类型的数据,“size_t”是“unsigned int”的别名。
  5. empty() :判断队列是否为空。此函数返回队列是否为空,返回值是bool类型。队列空:返回true;不空:返回false。

2. 示例程序

程序中,使用基本数据类型“string”以及自定义数据类型Data分别构造了优先级队列。然后通过运算符重载重写仿函数支持自定义的数据类型(两种方法都写了,代码中用的是运算符重载)。

#include <iostream>
#include <queue>//使用队列需要引用<queue>头文件
#include <string>
using namespace std;
//自定义数据类型,Data类
class Data
{
public:
	Data(int i, int d) :id(i), data(d) {}
	~Data() {}
	int getId() { return id; }
	int getData() { return data; }
	friend bool operator < (const Data &a, const Data &b);//运算符重载,友元函数可以访问类的私有成员
private:
	int id;
	int data;
};
//重载“<”运算符,仿函数less中需要使用
bool operator < (const Data &a, const Data &b) {
	return a.id < b.id;
}
//重写仿函数,完成less的功能,用class的时候,需要public关键词(因为struct中默认数据是public,而class中默认是private)
class cmp
{
public:
	bool operator() ( Data &a, Data &b) {
		return a.getId() < b.getId();
	}
};

int main()
{
	//基本数据类型示例
	priority_queue<string, vector<string>, greater<string> > p;//维护一个小顶堆,最小的元素优先级最高,最先出队
	p.push("C");
	p.push("B");
	p.push("A");
	cout << p.top() << endl;//队列中优先级最高的是最后进队的“A”
	//自定义数据类型示例
	priority_queue<Data, vector<Data>, less<Data> > priQueMaxFirst;//该优先级队列维护一个大顶堆,因此最大的元素最先出队
	//构造一个优先级队列
	for (int i = 0; i < 4; ++i) {
		Data tmpData(i, 0 - i);
		priQueMaxFirst.push(tmpData);
	}
	//打印当前队列中优先级最高的元素,然后将其出队
	while (!priQueMaxFirst.empty()) {
		Data topData = priQueMaxFirst.top();//top()与pop()搭配,获得队列中优先级最高的元素,然后将其出队
		priQueMaxFirst.pop();
		cout << "ID: " << topData.getId() << " " << " Data: " << topData.getData() << endl;//打印当前队列中优先级最高的元素
	}
	return 0;
}

上述程序的输出如下:

C++优先队列_队列queue中添加元素的方法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/190179.html原文链接:https://javaforall.net

(0)
上一篇 2026年2月25日 下午10:01
下一篇 2026年2月25日 下午10:43


相关推荐

  • graph representation learning_with for什么意思

    graph representation learning_with for什么意思刷新三数据集纪录的跨镜追踪(行人再识别-ReID)技术云从科技在跨镜追踪(行人再识别)技术(ReID)上获取重大突破。同时在Market-1501,CUHK03,DukeMTMC-reID三个数据集刷新了世界纪录,其中最高在Market-1501上的首位命中率(Rank-1Accuracy)达到96.6%,让跨镜追踪(ReID)在准确率上首次达到商用水平,人工智能即将从「刷脸」跨到「识人」的新纪…

    2022年10月6日
    4
  • Java反射(超详细!)[通俗易懂]

    Java反射(超详细!)[通俗易懂]1、反射机制有什么用?通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件。)通过反射机制可以操作代码片段。(class文件。)2、反射机制的相关类在哪个包下?java.lang.reflect.*;3、反射机制相关的重要的类有哪些?类含义java.lang.Class代表整个字节码。代表一个类型,代表整个类。java.lang.reflect.Method代表字节码中的方法字节码。代表类中的方法。java.lang.reflect.Con

    2022年5月30日
    38
  • 升降压电路的工作原理

    升降压电路的工作原理1.升压电路也叫自举电路,是利用自举升压二极管,自举升压电容等电子元件,使电容放电电压和电源电压叠加,从而使电压升高,有的电路升高的电压能达到数倍电源电压。开关直流升压电路(即所谓的boost或者step-up电路)原理,theboostconverter,或者叫step-upconverter,是一种开关直流升压电路,它可以是输出电压比输入电压高。基本电路图如图所示假定那个开关(三极管或者mos管)已经断开了很长时间,所有的元件都处于理想状态,电容电压等于输入电压。下面要分充电和放电两个部分来

    2022年6月20日
    66
  • FLAG_ACTIVITY_CLEAR_TOP的使用

    FLAG_ACTIVITY_CLEAR_TOP的使用本例使用FLAG_ACTIVITY_CLEAR_TOP退出整个应用程序:多activity中退出整个程序,例如从A->B->C->D,这时我需要从D直接退出程序。补充:finish()和system(0)都只能退出单个activity。我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在D窗口打开A窗口时在Intent中直接加入标志Int

    2022年7月17日
    14
  • 集群技术的简介_集群的分类

    集群技术的简介_集群的分类集群技术集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益,其任务调度则是集群系统中的核心技术。集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。中文名集群技术外文名…

    2025年6月2日
    7
  • Okio基本使用以及源码分析

    Okio基本使用以及源码分析Okio是什么在OkHttp的源码中经常能看到Okio的身影,所以单独拿出来学习一下,作为OkHttp的低层IO库,Okio确实比传统的java输入输出流读写更加方便高效。Okio补充了java.io和java.nio的不足,使访问、存储和处理数据更加容易,它起初只是作为OKHttp的一个组件,现在你可以独立的使用它来解决一些IO问题。先看下okio库中类之间的关系:okio中最关键的是对于缓存队列的管理,这些优化操作使得okio在复制数据的时候可以减少拷贝次数,来看下okio中数据保存的数据结构是

    2022年5月27日
    43

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号