目录
容器适配器概念
容器适配器是在C++标准库中提供的一种容器的封装。它们提供了一种统一的接口,使得不同类型的容器可以以相似的方式被使用。容器适配器有三种类型:栈(stack)、队列(queue)和优先队列(priority_queue)。其中优先队列其实就是数据结构中的堆(heap)。
我们看到这三种数据结构有一个共同的特点,那就是它们的规则是基于数据的,而不是基于内存的。比如说顺序表(vector)要求内存必须是连续的,链表(list)要求一个一个节点的形式来存储数据。它们都对内存有明确的限制。而以上三种数据结构,只是对数据的出入顺序有要求,所以它们的底层可以是vector,list等等其它容器。
也就是说,它们可以将原本的容器进行封装,改变容器的出入规则,但是底层的数据存储依然使用其它的容器。这种模式叫做容器适配器。
stack
栈(stack)是一种先进后出(Last-In-First-Out,LIFO)的数据结构,它的特点是只能在栈的一端进行插入和删除操作。在栈中,插入元素的一端称为栈顶(top),删除元素的一端称为栈底(bottom)。栈的插入操作叫做入栈(push),删除操作叫做出栈(pop)。
栈的实现通常有两种方式:数组实现和链表实现。使用数组实现的栈叫做顺序栈,使用链表实现的栈叫做链式栈。
先看到基本结构:
template <class T>
class stack
{
private:
vector<T> _con;
};
入栈:
入栈其实就是对vector尾插:
void push(const T& x)
{
_con.push_back(x);
}
出栈:
出栈就是对vector尾删:
void pop()
{
_con.pop_back();
}
返回栈顶元素:
返回栈顶,其实就是得到vector尾部的元素:
const T& top()
{
return _con.back();
}
返回栈的大小:
栈的大小,就是vector的大小:
size_t size()
{
return _con.size();
}
判断栈是否为空:
栈为空,其实就是vector为空:
bool empty()
{
return _con.empty();
}
如果用户想用list
做底层,难道我们又要写一个list
版本吗?
这是不需要的,我们不如直接传入第二个模板参数,让用户可以自定义需要的底层容器:
template <class T, class Container = vector<T>>
class stack
{
private:
Container _con;
};
第二个模板参数container
就是我们的底层容器,其默认值为vector
,当用户不传入第二个参数,那么默认以vector
为底层容器。
当用户需要lis