目录
前言
stack类就是数据结构中的栈
stack类所拥有的函数相比与string、vector和list类都少很多,这是因为栈这个数据结构是后进先出的,它必须被有所限制,所以所能用的函数只需要那几个足矣
栈可以用顺序表来实现,也可以用链表来实现,我们只需要控制它先进先出的特性即可,用什么容器实现取决于个人
因为我们前面实现了vector和list类,所以再实现stack类就容易很多了,只需要复用vector和list容器内的函数即可
数据结构
template<class T, class Container = std::deque<T>>
class stack
{
public:
private:
Container _con;
};
这里的模板有两个,T是栈的类型,Container表示的是所需要使用哪个容器来实现这个栈
我们需要用这个Container里面的成员函数来复用从而轻松的实现这个栈
这里的Container默认是deque
deque
deque(双端队列)也是STL中的一个容器,它是vector和list的结合
vector和list的优缺点
vector优点:
1. 随机访问效率高
2. 在内存中连续存储,缓存命中率高
vector缺点:
1. 插入和删除效率低
2. 空间分配不灵活(利用率低)
list优点:
1. 插入和删除效率高
2. 空间利用率高
list缺点:
1. 访问数据速度慢
2. 缓存利用率低(空间不连续,缓存命中率低)
为什么说deque是vector和list的结合?
下面是deque的数据结构图片
deque有n个buffer缓冲区(个数取决于数据个数)
这个缓冲区比list的空间大,像是一个小型数组,这个数组由中控器控制
而中控器可以通过一个数组来存储一个个的指针,这些指针又指向一个个缓冲区,所以它能够控制每一个缓冲区
iterator迭代器的cur、first和last来控制缓冲区的数据,node则表示是哪一个缓冲区
deque总结:
1. deque的头尾插入效率高
2. 下标的随机访问效率也还可以
3. 中间插入删除的效率很低(O(N))
push
void push(const T& x)
{
_con.push_back(x);
}
栈的push就是插入到最后的位置,所以只需要复用容器中的push_back函数即可
deque、vector和list都有这些函数,所以这三个容器都可以用来实现stack类
pop
void pop()
{
_con.pop_back();
}
栈的pop就是尾删,所以只需要复用pop_back函数即可
top
const T& top() const
{
return _con.back();
}
栈的top就是取尾部数据,返回back函数即可
size
size_t size() const
{
return _con.size();
}
栈的size就是取得栈的数据个数,返回容器的size函数即可
empty
bool empty() const
{
return _con.empty();
}
栈的empty就是判断栈是否为空,返回empty函数即可
只要上述的函数名哪个类中有,并且功能相同,就可以使用那个类来完成stack的实现
完整代码
#pragma once
#include<iostream>
#include<deque>
namespace lyw
{
template<class T, class Container = std::deque<T>>
class stack
{
public:
void push(const T& x)
{
_con.push_back(x);
}
void pop()
{
_con.pop_back();
}
const T& top() const
{
return _con.back();
}
size_t size() const
{
return _con.size();
}
bool empty() const
{
return _con.empty();
}
private:
Container _con;
};
}
完