C++ 容器适配器
前言
本文将会向你介绍容器适配器的使用
什么是容器适配器
适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。
适配器在queue、stack中的应用
stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:
- stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
- 在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;
}
小结
本文的分享就到这里啦,如果本文有存在疏漏或错误的地方还请您能够指出