【Stl配接器-stack和queue】

一、stack的介绍

1、什么是stack(栈)?

(1)stack是一种容器适配器(配接器),用在先进后出情境下,只能在容器的一端进行插入和删除操作。
(2)stack作为容器适配器,是对特定的类进行封装作为其底层容器,并提供一组特定的成员函数来访问其元素。
(3)stack支持任何标准容器类模板,或者一些特定类作为底层容器。不过一定要支持判空、获取尾部元素,尾插、尾删操作
(4)vector、list、deque具备上述功能,当没有指定stack的底层特定容器,默认情况下使用deque
在这里插入图片描述

2、stack的基本使用
在这里插入图片描述

(1)构造:stack(const container_type & ctnr=container_type())
(2)判空:bool empty()const
(3)返回有效元素个数:size_type size()const
(4)返回栈顶元素:value_type& top()const
(5)压栈:void push(const value_type&val);
(6)弹栈:void pop();
(7)交换:void swap(stack& x);
emplace:在栈顶构造新元素

二、queue的介绍
1、什么是队列?

(1)队列是一种容器适配器,在先进先出的环境下进行操作,从容器一端插入,另一端删除。
(2)元素从队尾入列,队头出列
(3)queue的底层容器应该支持以下操作:
判空、size、返回队头和队尾元素、队尾插入、队头删除。
(4)deque和list满足要求,一般情况下,用deque作为底层容器。

2、queue的基本操作
在这里插入图片描述

三、priority_queue的介绍
1、什么是priority_queue?

(1)优先队列也是一种容器适配器,它的第一个元素总是其元素中最大元素,并严格按照大小排序。
(2)它类似堆,可以随时插入元素,并且可以检索到最大堆元素
(3)成为priority_queue的基本待满足条件:

  • empty():判空
  • size():返回容器中有效元素个数
  • front():返回容器中第一个元素
  • push_back():容器尾部插入元素
  • pop_back():删除容器尾部元素
    (4)vector和deque满足要求,默认情况下,一般使用vector作为priority_queue的底层容器。
    (5)要支持迭代器随机访问,且在某些情况下会自动调用算法函数make_heap、push_heap和pop_heap自动来完成操作。

2、priority_queue的基本使用

优先队列默认使用vector作为底层容器,在vector上又使用了堆算法将vector中的元素构造成堆的结构,且priority_queue默认是大堆

#include<iostream>
#include<queue>//priority_queue需要包含的头文件
#include<vector>
#include<functional>//greater算法的头文件,默认是大堆

using namespace std;

void test()
{
	priority_queue<int>q;//默认是大堆 less
	
	vector<int>v = { 1, 2, 3, 4, 5, 6, 7 };
	priority_queue<int>a(v.begin(), v.end());
	while (!a.empty())
	{
		cout << a.top()<<" ";
		a.pop();
	}
	cout << endl;//结果:7,6,5,4,3,2,1

	a.push(10);
	a.push(0);
	a.push(1);
	a.push(1);//可以有相同元素的存在
	while (!a.empty())
	{
		cout << a.top() << " ";
		a.pop();
	}
	cout << endl;

	//建小堆
	priority_queue<int, vector<int>, greater<int>>b(v.begin(),v.end());//小堆
	while (!b.empty())
	{
		cout << b.top() << " ";
		b.pop();
	}
	cout << endl;
	priority_queue<int, vector<int>, less<int>>c(v.begin(), v.end());//默认大堆
	while (!c.empty())
	{
		cout << c.top() << " ";
		c.pop();
	}
	cout << endl;

}

(1)构造空的队列:
在这里插入图片描述
注意这里的参数顺序,priority_queue<int, vector<int>, greater<int>>b(v.begin(),v.end());
(2)判空:bool empty()const
(3)返回堆顶元素:const value_type& top()const
(4)插入:void push(const T& x)
(5)删除:void pop()
(6)建小根堆,将第三个参数改为greater

  • 如果在priority_queue中放自定义类型的数据,用户需要在自定义类里面重载小于<或者大于>号(主要根据其是大或小堆来定)
  • 也可自己定义比较函数,在存入的是自定义类型情况下需要自己定义比较规则(仿函数,小括号的重载)
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
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}
	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}
	friend ostream& operator<<(ostream& _cout, const Date& d)
	{
		_cout << d._year << "-" << d._month << "-" << d._day;
		return _cout;
	}
private:
	int _year;
	int _month;
	int _day;
};

class Less
{
public:
	bool operator()(const Date* pLeft, const Date* pRight)
	{
		return *pLeft < *pRight;
	}
};
void TestPriorityQueue()
{
	// 自己定制比较的规则
	priority_queue<Date*, vector<Date*>, Less> q;
	q.push(&Date(2018, 10, 29));
	q.push(&Date(2018, 10, 28));
	q.push(&Date(2018, 10, 30));
	cout << *q.top() << endl;
}

四、容器适配器

1、什么是适配器?

适配器是一种设计模式,可以将一个类的接口转换为客户希望的另一个接口。

2、为什么stack、queue、priority_queue是容器适配器而不是容器呢?

因为每个容器在底层都有自己的实现方式,但是stack、queue、priority_queue在底层只是将其他容器进行了封装得到的。
比如:stack是对deque的封装,queue是对deque的封装,priority_queue是对vector的封装

//stack
template<class T,class Container=deque<T>> class stack;
//queue
template<class T,class Container=deque<T> > class queue;
//priority_queue
template<class T,class Container=vector<T>>,
class Compare=less<typename Container::value_type>>class priority_queue;

3、为什么选择deque作为stack和queue的底层默认容器?

(1)stack和queue没有迭代器,不需要遍历,只需要在固定一段或两端进行操作。
(2)stack在增长时,deque比vector的效率高;queue中元素在增长的时候,deque不仅效率比list高,而且内存利用率也高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值