priority_queue 优先队列概念以及常见用法

目录

1. priority_queue简单介绍

2. priority_queue代码测试

1. priority_queue简单介绍

①在优先队列中,元素被赋予优先级(按约定的函数来赋予优先级,底层通过堆来实现)。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。

②优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。

③定义: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(),这个类就有了类似函数的行为,就是一个仿函数类了

2. priority_queue代码测试

各部分结果见注释:

#include <queue>
#include <list>
#include <functional>

void TestPriorityQueue1()
{
	priority_queue<int> q;
	q.push(4); //注意是push 不是push_back
	q.push(1);
	q.push(5);
	q.push(3);
	q.push(7);
	q.push(2);
	q.push(6);

	cout << q.size() << endl; //7
	cout << q.top() << endl; //7

	q.pop();
	q.pop();

	// 注意:堆顶元素不能修改,因为修改之后可能不能满足堆的特性
	cout << q.top() << endl; //5
}

void TestPriorityQueue2()
{
	list<int> L{4,1,5,3,7,2,6};
	priority_queue<int, vector<int>, greater<int>> q(L.begin(), L.end()); //构建的是小根堆
	

}

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	bool operator<(const Date& d)const
	{
		if ((_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day))
		{
			return true;
		}

		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};


void TestPriorityQueue3()
{
	priority_queue<Date> q; //存放的是自定义类型

	Date d1(2022, 5, 29);
	Date d2(2022, 5, 28);
	Date d3(2022, 5, 30);

	q.push(d1);
	q.push(d2);
	q.push(d3); //2022 5 30    2022 5 28    2022 5 29
}


bool LessFunc(const Date* left, const Date* right)
{
	return *left < *right;  //这里不能改为> 因为Date里没有>运算符重载
}

typedef bool (*LessF)(const Date*, const Date*); //声明LessF为一个类型

//注意<>里必须放的是类型(类似模板) 所以用typedef将LessF看作类型
void TestPriorityQueue4()
{
	priority_queue<Date*, vector<Date*>, LessF> q(LessFunc);

	Date d1(2022, 5, 29);
	Date d2(2022, 5, 28);
	Date d3(2022, 5, 30); 

	q.push(&d1);
	q.push(&d2);
	q.push(&d3); //2022 5 30    2022 5 28    2022 5 29
}

// 如果想要让一个类的对象按照函数调用的方式进行使用
// 还需在该类中将()即“函数调用运算符”重载即可   ---推荐使用该方法而不是上面的方法
class Less
{
public:
	bool operator()(const Date* left, const Date* right)const
	{
		return *left < *right;
	}
};

//推荐用TestPriorityQueue5这种方法,写个类,重载(),然后就可以用Less。
void TestPriorityQueue5()
{
	priority_queue<Date*, vector<Date*>, Less> q;

	Date d1(2022, 5, 29);
	Date d2(2022, 5, 28);
	Date d3(2022, 5, 30);

	q.push(&d1);
	q.push(&d2);
	q.push(&d3);

	Less lessObj;
	lessObj.operator()(&d1, &d2);//也可以写成下面的形式

	// lessObj不是函数名,而是Less的一个对象
	// lessObj: 函数对象----就是可以像函数调用一样使用的对象
	// 也称为仿函数
	lessObj(&d1, &d2);

	// LessFunc是一个真正的函数
	LessFunc(&d1, &d2);
}

int main()
{
	 //TestPriorityQueue1();
	 //TestPriorityQueue2();
	 //TestPriorityQueue3();
	 //TestPriorityQueue4();
	 TestPriorityQueue5();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值