文章目录
- 💐专栏导读
- 💐文章导读
- 🌷stack是什么?
- 🌷stack的基本使用
- 🌷stack的模拟实现
- 🌷queue是什么?
- 🌷queue的基本使用
- 🌷queue的模拟实现
💐专栏导读
🌸作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。
🌸本文收录于 C++系列,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新!
🌸相关专栏推荐:C语言初阶系列 、C语言进阶系列 、数据结构与算法
💐文章导读
本章我们将学习stack
与queue
的基本使用以及模拟实现。stack
与queue
同样也是我们最先接触到的STL
六大组件之一的容器适配器
。
🌷stack是什么?
在ST
L中,stack
是一个模板类
,用于实现栈数据结构。栈是一种后进先出(LIFO
)的数据结构,可以在栈顶进行插入和删除操作。
stack
是一种容器适配器
,容器适配器不是容器类型本身,而是对现有的容器类型
进行了一定程度的封装和改造,从而形成了一种新的容器类型。
stack
类封装了一个底层容器
,可以使用多种不同的容器作为其底层实现,比如deque
和vecto
r等。
stack
的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:
empty
:判空操作;back
:获取尾部元素操作;push_back
:尾部插入元素操作;pop_back
:尾部删除元素操作;
标准容器vector
、deque
、list均符合这些需求,默认情况下,如果没有为stack
指定特定的底层容器,默认情况下使用deque
。
至于deque
是什么我们先不深究,我们就当它是vector
一样,后面会讲到。
🌷stack的基本使用
- 🍁使用stack之前需要包含头文件
< stack >
;
#include <stack>
- 🍁定义一个栈对象;
stack<int> s;
- 🍁将元素压入栈中;
//push()s.push(1);s.push(2);s.push(3);
- 🍁访问栈顶元素;
//top()cout << s.top() << endl;
- 🍁弹出栈顶元素;
//pop()s.pop();
- 🍁获取栈的大小;
//size()cout << "Size of stack: " << s.size() << endl;
- 🍁判断栈是否为空;
//empty()if (s.empty()){cout << "Stack is empty" << endl;}else{cout << "Stack is not empty" << endl;}
🌷stack的模拟实现
我们已经知道栈是一个容器适配器,底层封装了其它容器,所以栈的实现非常简单,在实现各个函数接口时,我们直接复用封装的容器的相关接口即可。
不同于vector
与list
的模拟实现,stack
需要两个模板参数:
参数类型
;容器类型
;
我们可以在自己的命名空间中定义stack
类,如下:
namespace hxy
{template<class T, class Container = vector<T>>class stack{public:void push(const T& data){//...}void pop(){//...}const T& top(){//...}size_t size(){//...}bool empty(){//...}private:Container _con;};
}
接下来就是实现各个接口了。作为容器适配器,stack
的各接口实现极其简单,用一分钟实现一个栈来描述也不是太夸张,一起来看看吧。
namespace hxy
{template<class T, class Container = vector<T>>class stack{public:void push(const T& data){_con.push_back(data);}void pop(){_con.pop_back();}const T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};}
因为容器适配器是封装了一层容器的,所以可以直接调用底层容器的接口供自己使用。现在再回头看文章开头对于容器适配器的描述,应该能深刻理解了。
🌷queue是什么?
queue
与stack
非常相似。在STL
中,队列(queue
)是一种基本的数据结构,它是一种先进先出(FIFO
)的数据结构。队列可以看作是一条通往某个目的地的等待队列,其中最先进入的元素首先被处理,而最后进入的元素则最后被处理。
与stack
相同,queue
同样也是一个容器适配器
,queue
与stack
对比起来学习会更加轻松。
🌷queue的基本使用
- 🍁包含头文件
< queue >
;
#include <queue>
- 🍁定义一个
queue
对象;
queue<int> q;
- 🍁元素入队(队尾添加元素);
//push()q.push(1);q.push(2);q.push(3);
- 🍁元素出队(队头删除元素);
//pop()q.pop();
- 🍁访问队头元素;
- 🍁访问队尾元素;
//front()//back()cout << q.front() << endl;cout << q.back() << endl;
- 🍁获取队列的大小;
//size()cout << q.size() << endl;
- 🍁判断队列是否为空;
//empty()if (q.empty()){cout << "Queue is empty" << endl;}else{cout << "Queue is not empty" << endl;}
🌷queue的模拟实现
queue
与stack
的实现方式大同小异,此处不做赘述。
namespace hxy
{template<class T, class Container = list<T>>class queue{void push(){_con.push_back();}void pop(){_con.pop_front();}const T& front(){_con.front();}const T& back(){_con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;}
本章节的内容就到这里了。下一章我们将学习双端队列——deque
和优先级队列——priority_queue
,认识了双端队列,我们就能明白为什么库中的stack
与queue
要使用deque
来做底层容器了。
点击下方个人名片,可添加博主的个人QQ,交流会更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓