【c++容器】priority_queue的常见用法详解

priority_queue又称为优先队列,其底层是用来进行实现的。在优先队列中,队首元素一定是当

前队列中优先级最高的那一个。例如在队列有如下元素,且定义好了优先级:

桃子(优先级3)
 
梨子(优先级4)
 
苹果(优先级1)

那么出队的顺序为梨子(4)→桃子(3)→苹果(1)。

当然,可以在任何时候往优先队列里面加入(push)元素,而优先队列底层的数据结构堆(heap)会随

时调整结构,使得每次的队首元素都是优先级最大的。

关于这里的优先级则是规定出来的。例如上面的例子中,也可以规定数字越小的优先级越大。

要使用优先队列,应先添加头文件#include,并在头文件下面加上“using namespace

std;”。

1.priority_queue的定义

定义的写法和其他STL容器相同, typename可以是任意基本数据类型或容器:

priority_queue name;

2.priority_queue容器内元素的访问

和队列不一样的是,优先队列没有front()函数与 back()函数,而只能通过top()函数来访问队首元

(也可以称为堆顶元素),也就是优先级最高的元素。

程序代码:

#include 
#include
using namespace std;
int main(int argc,char** argv) {
	priority_queue q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.top());
	return 0; 
}

运行结果:

【c++容器】priority_queue的常见用法详解_第1张图片

 如上所示,队首元素都是优先级最大的,队首元素是4。

3.priority_queue常用函数实例解析

(1)push()
push(x)将令x入队,时间复杂度为O(logN),其中N为当前优先队列中的元素个数。实例见“ priority

queue容器内元素的访问”。

(2)top()
top()可以获得队首元素(即堆顶元素),时间复杂度为O(1),实例见" priority_queue容内元素的访

问”。

使用top()函数前,必须用empty()判断优先队列是否为空。

(3)pop()
pop()可令首元素(即堆顶元素)出队,时间复杂度为O(logN)。

在使用pop()函数前,必须用empty()判断优先队列是否为空。

程序代码:

#include 
#include
using namespace std;
int main() {
	priority_queue q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.top());
	q.pop(); 
	printf("%d\n",q.top());
	return 0; 
}

【c++容器】priority_queue的常见用法详解_第2张图片

(4)empty()

empty()检测优先队列是否为空,空则返回true,非空则返回false,时间复杂度O(1)。

程序代码:

 

#include 
#include
using namespace std;
int main(){
	priority_queue q;
	printf("%d\n",q.empty());	//先开始没有元素,为空(true);输出 1
	q.push(3);
	printf("%d\n",q.empty());	//压入元素,为非看(false);输出 0
	return 0; 
}

【c++容器】priority_queue的常见用法详解_第3张图片 (5)size()

size()返回优先队列内元素的个数,时间复杂度O(1)。

程序代码:

#include 
#include
using namespace std;
int main(){
	priority_queue q;
	for(int i=0;i<=3;i++) {
		q.push(i);
	}
	printf("%d\n",(int)q.size());	//输出队列元素个数 
	return 0; 
}

 【c++容器】priority_queue的常见用法详解_第4张图片

4. priority_ queue内元素优先级的设置

如何定义优先队列内元素的优先级是运用好优先队列的关键

(1)基本数据类型的优先级设置

此处指的基本数据类型就是int型、 double型、char型等可以直接使用的数据类型,优先队列对它

们的优先级设置一般是数字大的优先级越高,因此队首元素就是优先队列内元素最大的那个(如果

char型,则是字典序最大的)。对基本数据类型来说,下面两种优先队列的定义是等价的(以int型为

例,注意最后两个>之间有一个空格)

priority_queue q;
priority_queue, less > q;
priority_queue, greater > q;

在后二种定义的方式中,多出了两个参数,vector<>和less<>(greater<>)。

第二个参数vector<>是用来承载底层数据结构堆(heap)的容器;

第三个参数less<>或者greater<>是对第一个参数的比较类,less表示数字越大优先级越大,

greater表示数字越小,优先级越大。

程序代码:

#include
#include
using namespace std;
int main(){
	priority_queue, greater > q;
	q.push(3);
	q.push(1);
	q.push(4);
	printf("%d\n",q.top());	 
	return 0; 
}

【c++容器】priority_queue的常见用法详解_第5张图片

 按照正常来说,队头元素应该是最大的元素4,但greater表示数字越小,优先级越大,结果是1。

事实上,基本数据类型也可以使用结构体的优先级设置方法

(2)结构体的优先级设置

建立结构体,并重载小于号 “<” :

struct fruit {
	string name;
	int price;
	//重载小于号
	friend bool operator < (fruit f1, fruit f2)  {
		return f1.price

定义优先队列:

priority_queue q;

重载是对已有的运算符进行重新定义,在fruit结构体中添加一个函数,其中“friend”是友元;后面的

“bool operator < (fruit f1,fruit f2)”对fruit类型的操作符“<”进制了重载;函数的内部为“return

f1.price

列,其内部以价格高的水果为优先级高。同理想要以价格低的水果为优先级高,那么只需要把

return中的小于号改为大于号即可。

程序代码:

#include 
#include
#include
using namespace std;
struct fruit {
	string name;
	int price;
	//重载小于号,价格高的优先级高 
	friend bool operator < (fruit f1, fruit f2)  {
		return f1.price q;
	f1.name = "桃子";
	f1.price = 3;
	f2.name = "梨子";
	f2.price = 4;
	f3.name = "苹果";
	f3.price = 1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout << q.top().name << " " << q.top().price << endl;
	return 0; 
}

【c++容器】priority_queue的常见用法详解_第6张图片

注意:

重载大于号会编译错误,因为从数学上来说只需要重载小于号,即判断f1>f2等价于判断f2

f1==f2则等价于判断!(f1

【c++容器】priority_queue的常见用法详解_第7张图片此处对小于号的重载与排序函数sort中的cmp函数有些相似,它们的参数都是两个变量,函数内部

都是 return了true或者 false。事实上,这两者的作用确实是类似的,只不过效果看上去似乎是“相

反”的。在排序中,如果是“ return f1.price>f2. price”,那么则是按价格从高到低排序,但是在优先

队列中却是把价格低的放到队首。原因在于,优先队列本身默认的规则就是优先级高的放在队首,

因此把小于号重载为大于号的功能时只是把这个规则反向了一下。优先队列的这个函数与sort中的

cmp函数的效果是相反的。

当然也可以将重载的函数写在结构体外面

struct cmp {
	bool operater () (fruit f1,fruit f2) {
		return f1.price > f2.price;
	}
}; 

 定义优先队列:

priority_queue,cmp> q;

程序代码:

#include 
#include
#include
using namespace std;
struct fruit {
	string name;
	int price;
}f1,f2,f3;
struct cmp {
	bool operator () (fruit f1, fruit f2) {
		return f1.price < f2.price;
	}
}; 
int main(){
	priority_queue,cmp> q;
	f1.name = "桃子";
	f1.price = 3;
	f2.name = "梨子";
	f2.price = 4;
	f3.name = "苹果";
	f3.price = 1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout << q.top().name << " " << q.top().price << endl;
	return 0; 
}

【c++容器】priority_queue的常见用法详解_第8张图片

同样,即便是基本数据类型或者其他STL容器,如(set), 也可以通过同样的方式来定义优先级

最后指出,如果结构体内数据庞大,像出现字符串或者数组,建议使用引用来提高效率。此时比较

类的参数需要加上“const ” 和 “&”,如下所示: 

friend bool operator < (const fruit &f1, const fruit &f2) {
		return f1.price < f2.price;
}
bool operator () (const fruit &f1, const fruit &f2) {
		return f1.price < f2.price;
}

转载:https://blog.csdn.net/qq_42410605/article/details/100537452?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163063047716780366530718%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163063047716780366530718&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-100537452.pc_search_result_cache&utm_term=priority_queue&spm=1018.2226.3001.4187

你可能感兴趣的:(STL,C&C++记录学习,c++)