C++ 容器适配器

前言

本文将会向你介绍容器适配器的使用

什么是容器适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

适配器在queue、stack中的应用

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

  1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。

引入

deque是C++ STL中的一个容器,全称为double-ended queue,即双端队列。它是一种能够在两端进行插入和删除操作的序列容器,支持随机访问。
vector支持下标随机访问但不支持头插头删,或者说性能很低,list头插头删效率都极高,中间插入效率也高,但是不支持下标随机访问。而deque既支持下标随机访问,头插头删效率也比较高,可以说是结合了vector和list优点。
deque是有一个存放数组指针的数组,每个数组指针指向一个数组,用来存放元素,相比于vector头插头删就不需要挪动数据,效率很高,相比于list空间利用率高,list是一块一块的占用内存,导致会出现比较多的内存碎片。

在这里插入图片描述
虽然在stack和queue中也可以存放元素,但是STL标准库中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque
在这里插入图片描述

在这里插入图片描述

queue

namespace Fan
{
template<class T, class Con = deque<T>>//模板参数,T是数据类型,Con是容器,默认是deque
class queue
{
public:
	void push(const T& x)
	{
		_c.push_back(x); //调用队列的尾插
	}
	void pop()
	{
		_c.pop_front(); //调用队列的头删
	}
	T& back()
	{
		return _c.back(); //返回队列的最后一个元素的引用
	}
	const T& back() const
	{
		return _c.back(); //const:返回队列的第一个元素的常量引用
	}	
	T& front()
	{
		return _c.front(); //返回队列的第一个元素的引用
	}
	const T& front() const
	{
		 return _c.front(); //返回队列第一个元素的常量引用
	}
	size_t size() const
	{
		return _c.size(); //返回队列的大小
	}
	bool empty() 
	{
		return _c.empty(); //判断队列是否为空
	}
private:
	Con _c;
	};
};
//test
int main()
{
	Fan::queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);
	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}
	return 0;
}

stack

namespace Fan
{
	template<class T, class Con = deque<T>> //模板参数是T和Con,默认容器类型是deque<T>
	class stack
	{
	public:
		void push(const T& x)
		{
			_c.push_back(x); //元素入栈
		}
		void pop()
		{
			_c.pop_back(); //将栈顶元素删除
		}
		T& Top()
		{
			return _c.back(); //输出栈顶元素
		}
		const T& Top() const
		{
			return _c.back(); //const版本,输出栈顶元素
		}
		size_t size() const
		{
			return _c.size(); //返回栈的大小
		}
		bool empty() const
		{
			return _c.empty(); //判断栈是否为空
		}
	private:
		Con _c;
	};
};
//test
int main()
{
	Fan::stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	st.push(4);
	st.push(5);
	while (!st.empty())
	{
		cout << st.Top() << " ";
		st.pop();
	}
	return 0;
}

小结

本文的分享就到这里啦,如果本文有存在疏漏或错误的地方还请您能够指出

posted @ 2023-10-22 10:50  Fan_558  阅读(9)  评论(0编辑  收藏  举报  来源