【C++ STL】容器适配器 Container adapter(stack & queue & priority_queue)

一、STL - stack

1.1 stack 的介绍
image-20220520170638655

文档介绍:stack - C++ Reference (cplusplus.com)

// T: 容器中存储的元素的类型
template <class T, class Container = deque<T> > class stack;
  1. stack 是一种「容器适配器」(container adapter),专门用在具有 LIFO (后进先出) 操作的上下文环境中,其中元素仅从容器的一端插入和提取。

  2. stack 是作为容器适配器被实现的,「容器适配器」即是「对特定容器类封装」作为其底层的容器,并提供一组特定的成员函数来访问其元素,元素从特定容器的尾部(即栈顶)被压入和弹出,这被称为堆栈的顶部。

  3. stack 的底层容器可以是任何标准容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作

    • empty:判空操作

    • size:获取有效元素个数

    • back:获取尾部元素操作

    • push_back:尾部插入元素操作

    • pop_back:尾部删除元素操作

  4. 标准容器类 vector、deque、list 均符合这些要求,默认情况下,如果没有为 stack 指定特定的底层容器类,则使用标准容器双端队列 deque

容器适配器/配接器:不是直接实现的,封装其他容器,包装转换实现出来的。


1.2 stack 的使用

stack 没有迭代器,有了迭代器就可以随意访问元素了,不能保证「后进先出」的性质了。

成员函数 接口说明
stack() 构造一个堆栈容器适配器对象,构造空的栈。
empty 检查 stack 是否为空
size 返回 stack 中有有效元素的个数
top 返回栈顶元素的引用
push 压栈,将一个元素压入 stack 中
pop 出栈,将 stack 尾部元素弹出
swap(C++11) 交换两个容器的内容(该成员函数调用非成员函数 std::swap 来交换底层容器)

👉 Example:

void test_stack1()
{
   
	stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);

	// 遍历堆栈中的元素
	while (!st.empty())
	{
   
		cout << st.top() << " ";
		st.pop();
	}
}

1.3 stack 的模拟实现

不需要写构造函数,因为在默认构造函数的初始化列表阶段,自定义类型成员 _con 会自动调用它的默认构造函数

namespace winter
{
   
	/*
	* T: 堆栈中存储的数据的类型
	* Container: 适配堆栈的容器类型,默认为deque
	*/
	template<class T, class Container = std::deque<T>>
	class stack
	{
   
		// stack 是一个 Container 适配(封装转换)出来的
		// 把 Contariner 的尾部认为是栈顶

	public:
		bool empty() // 判空
		{
   
			return _con.empty();
		}

		size_t size() const // 获取有效元素的个数
		{
   
			return _con.size();
		}

		const T& top() const // 返回栈顶元素的引用
		{
   
			return _con.back();
		}

		void push(const T& val) // 压栈,尾插
		{
   
			_con.push_back(val);

			// 大家可能会有疑问,如果 _con 没有 push_back 接口怎么办呢?
			// 没有就报错呗,说明你不能适配我
		}

		void pop() // 出栈,尾删
		{
   
			_con.pop_back();
		}

		// C++11
		void swap(stack<T, Container>& st) // 交换两个容器的内容
		{
   
			// 注意:底层调用的是非成员函数 std::swap 来交换底层容器
			std::swap(_con, st._con);
		}

	private:
		Container _con; // 适配的容器
	};
    
    // 测试
    void test1()
	{
   
		//stack<int, std::vector<int>> st; // 用vector适配
		//stack<int, std::list<int>> st;   // 用list适配
		stack<int> st; // 默认用deque适配
		st.push(1);
		st.push(2);
		st.push(3);

		// 遍历堆栈中的元素
		while (!st.empty())
		{
   
			cout << st.top() << " ";
			st.pop();
		}
		cout << endl;
	}
}

二、STL - queue 的介绍

2.1 queue 的介绍
image-20220520170618587

文档介绍:queue - C++ Reference (cplusplus.com)

// T: 容器中存储的元素的类型
template <class T, class Container = deque<T> > class queue;
  • 队列是一种「容器适配器」(container adapter),专门用于在 FIFO (先进先出) 操作的上下文环境中,其中从容器一端插入元素,另一端提取元素。

  • 队列作为容器适配器实现,「容器适配器」即「对特定容器类封装」作为其底层容器类,queue 提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

  • 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作

    • empty:检测队列是否为空

    • size:返回队列中有效元素的个数

    • front:返回队头元素的引用

    • back:返回队尾元素的引用

    • push_back:在队列尾部入队列

    • pop_front:在队列头部出队列

  • 标准容器类双端队列 deque 和带头双向循环链表 list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标准容器双端队列 deque


2.2 queue 的使用

注意:queue 没有迭代器,有了迭代器就可以随意访问元素了,不能保证「先进先出」的性质了。

成员函数 接口说明
queue() 构造一个队列容器适配器对象。构造空的队列
empty 检测队列是否为空
size 返回队列中有效元素的个数
front 返回队头元素的引用
back 返回队尾元素的引用
push 入队,将一个元素从队尾入队列
pop 出队,将队头元素出队列
swap (C++11) 交换两个容器的内容(该成员函数调用非成员函数 std::swap 来交换底层容器)

👉 Example:

void test_queue1()
{
   
	queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);

	// 遍历队列中的元素
	while (!q.empty())
	{
   
		cout << q.front() << " ";
		q.pop();
	}
}

2.3 queue 的模拟实现

不需要写构造函数,因为在默认构造函数的初始化列表阶段,自定义类型成员 _con 会自动调用它的默认构造函数

namespace winter
{
   
	/*
	* T: 队列中存储的数据的类型
	* Container: 适配队列的容器类型,默认为deque
	*/
	template<class T, class Container = std::deque<T>>
	class queue
	{
   
	public:
		bool empty() // 判空
		
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值