【C++】容器适配器Stack和Queue
stack和queue的使用
stack
stack简单介绍
stack就是数据结构中的栈,栈的特点就是后入先出,stack并不是容器,而是容器适配器,容器适配器是对特定类(这里特定的类比如vector,list,deque)封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的容器,特定容器的尾部(这里的尾部就是栈顶)被压入和弹出。
stack的底层容器可以是任何标准容器的类模板,这些底层容器必须要支持以下操作:
尾插push_back、尾删pop_back、获取尾部元素back、判断容器是否为空empty、获取容器有效元素个数size。
vector、list、deque(双端队列),这些容器都可以作stack的底层容器,如果使用stack没有指定特定的容器,默认的底层容器就是deque。
deque这个容器能用到它的地方比较少,它就属于是那种六边形战士,什么都会一点,但是样样不精通,所以一般很少会用它,但是它就非常适合作stack和下面要讲的queue的底层容器。
双端队列的函数接口如下:
stack的使用介绍
使用stack前,要包一个头文件如下:
#include <stack>
stack有以下几个函数接口:
stack():构造函数
push():插入,从栈顶压入
pop():删除,从栈顶弹出
top():返回栈顶元素的引用
size():返回栈中的有效元素的个数
empty():判断栈是否为空,是返回true,否则返回false
queue
queue简单介绍
queue就是数据结构中的队列,队列的特点就是先入先出,在容器的一端插入数据,另一端删除数据。queue和stack一样都是容器适配器,不是容器。queue将特定容器类封装,作为其底层容器类,queue提供特定的成员函数接口来访问其元素,元素从队尾入队列,从队头出队列。
queue底层容器必须要具备以下功能:
尾插push_back、尾删pop_front、返回队列中有效元素的个数size、返回队头元素的引用front、返回队尾元素的引用back、检查队列是否为空empty。
queue使用的默认的底层容器和stack一样都是deque(双端队列)。
queue的使用介绍
queue在使用前,也要包一个头文件
#include<queue>
queue的函数接口如下:
queue(): 构造空的队列
empty(): 检测队列是否为空,是返回true,否则返回false
size(): 返回队列中有效元素的个数
front(): 返回队头元素的引用
back(): 返回队尾元素的引用
push(): 在队尾将元素val入队列
pop(): 将队头元素出队列
stack和queue的模拟实现
stack的模拟实现
stack的模拟实现也非常简单,只需要把底层容器的接口封装以下即可。
stack是可以指定底层容器的所以它的模板要这么写。
template <class T, class Container = deque<T>>
class stack
{
public:
private:
Container _con;
};
stack的构造函数,我们不需要写,默认生成的就可以。
push
要模拟push,直接对push_back进行封装,就可以实现压栈的操作。
void push(const T& val)
{
_con.push_back(val);
}
pop
要模拟pop,直接对pop_back进行封装,就可以实现出栈的操作。
void pop()
{
_con.pop_back();
}
这里不需要对栈进行判空,因为这个操作pop_back就帮我们做了。
top
top:返回栈顶值的引用,对back进行封装即可。
T& top()
{
return _con.back();
}
empty
对底层容器的empty封装即可。
bool empty()
{
return _con.empty();
}
size
对底层容器的size封装即可。
size_t size()const
{
return _con.size();
}
stack模拟实现的全部代码
#pragma once
#include <deque>
namespace lzq
{
template <class T, class Container = deque<T>>
class stack
{
public:
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
T& top()
{
return _con.back();
}
bool empty()
{
return _con.empty();
}
size_t size()const
{
return _con.size();
}
private:
Container _con;
};
}
queue的模拟实现
queue的模拟实现也非常简单,和stack一样,只需要把底层容器的接口封装以下即可。
queue也是可以指定底层容器的所以它的模板也要这么写。
template <class T, class Container = deque<T>>
class queue
{
public:
private:
Container _con;
};
queue的构造函数,我们不需要写,默认生成的就可以。
push
push:直接对push_back进行封装,就可以实现入队的操作。
void push(const T& val)
{
_con.push_back(val);
}
pop
pop:直接对pop_front进行封装,就可以实现出队的操作。
void pop()
{
_con.pop_front();
}
这里不需要对栈进行判空,因为这个操作pop_back就帮我们做了。
front
front:返回队头值的引用,对front进行封装即可。
T& front()
{
return _con.front();
}
back
back:返回队尾值的引用,对back进行封装即可。
T& back()
{
return _con.back();
}
empty
对底层容器的empty封装即可。
bool empty()
{
return _con.empty();
}
size
对底层容器的size封装即可。
size_t size()const
{
return _con.size();
}
queue模拟实现的全部代码
#pragma once
#include <deque>
namespace lzq
{
template <class T, class Container = deque<T>>
class queue
{
public:
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
T& front()
{
return _con.front();
}
T& back()
{
return _con.back();
}
bool empty()
{
return _con.empty();
}
size_t size()const
{
return _con.size();
}
private:
Container _con;
};
}