STL之stack和queue

写在前面:

之前已经介绍过stl 的序列式容器 --deque 双端队列,而stack和queue正是按照其自身不同的接口需求,在默认的情况下使用deque的底层结构适配出来的两个适配器,因为satck和queue只需要满足size、empty、push、pop、top的基本操作就可以了,而这些操作像deque、list都可以轻易的实现
stack 只能在一端进行插入删除操作的栈(后进先出)
queue 数据在一头进行入队,在另一头进行出队的队列(先进先出)

目录:

  1. stack简介与使用
  2. queue简介与使用
  3. 实现一个stack

Stack 栈

逻辑模型:

只允许在栈顶进行进栈出栈,遵循后进先出的原则

在这里插入图片描述

这里所说的后进先出是相对于栈里面的元素
例如 进栈的顺序是

1234

出栈的顺序不一定一定是:

4321

也有可能是:

1234//这是因为按照进栈的顺序1进栈又立马出栈,2、3、4也是如此 
2134//先将1、2进栈,然后这时候2相对于1来说后进,所以2出栈,再将1出栈
2341/1,3,4,2/....等等出栈的顺序还有很多种

一、头文件<stack>

二、简介

在这里插入图片描述

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行 元素的插入与提取操作。
  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下 操作: empty:判空操作 back:获取尾部元素操作 push_back:尾部插入元素操作 pop_back:尾部删除元素操作
  4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器, 默认情况下使用deque

三、构造函数

不像其他的容器,像stack和queue这样的容器适配器只有简单的构造函数

stack<T> s; 构造空的stack对象
stack<T> s1(s); 使用s 拷贝构造s1对象;

例如:

stack <int> s;
s.push(1);
s.push(2);
stack <int> s1(s);
int len=s1.size();
for(i=0; i<len;i++)//不能使用循环遍历只能循环出栈取栈顶元素

{
	cout<<s1.top()<<endl;
	s1.pop();
}

在这里插入图片描述
注意:

当栈为空时不能再进行top和pop操作,这样会导致非法访问,导致程序崩溃。

四、大小、是否为空、插入、删除等操作

函数说明接口说明
bool empty() const检测stack是否为空
size_type size() const返回stack中元素的个数
value_type& top()返回栈顶元素的引用
const value_type& top() const返回栈顶元素的const引用
void push (const value_type& val)将元素val压入stack中
void pop()将stack中尾部的元素弹出
template <class… Args> void emplace (Args&&… args) (C++11)在stack的栈顶构造元素
void swap (stack& x) (C++11)交换两个栈中的元素

示例:
emptysize

	stack<int> s2;
	s2.push(1);
	s2.push(2);
	if (s2.empty())//empty 测试stack是否为空 为空返回真  否则返回 false
	{
		cout << "empty" << endl;
	}
	else
	{
		cout <<"not empty and size="<< s2.size()<<endl;
	}

在这里插入图片描述
top、push、pop
top是取栈顶的元素,对栈顶元素可读可写,返回的是const top时 只能读不能写

	stack<int> s1;
	s1.push(1);
	s1.push(2);
	s1.top() = 4;//可写
	cout << s1.top() << endl;//可读
	const stack<int> s2(s1);
	cout << s2.top() << endl;//只能读

在这里插入图片描述
这种适合于,当将这个stack传参不希望别人修改,只允许别人读时,传一个const对象
在这里插入图片描述

在这里插入图片描述
push、pop进栈、出栈

	stack<int> s1;
	s1.push(1);
	cout << s1.top() << endl;
	s1.push(2);
	cout << s1.top() << endl;
	s1.pop();
	cout << s1.top() << endl;

在这里插入图片描述
注意,当pop时要注意栈是否为空,否则将引发非法操作
swap
交换两个栈的元素,在底层实现其实就是交换两个对象的地址
示例:
在这里插入图片描述
emplace 在stack的栈顶构造元素
示例:

stack<int> s;
s.emplace(3);//效果于push一样

五、遍历元素

stack 不支持随机访问也不支持遍历访问,因此也是没有迭代器的存在的,只能通过循环的进行取栈顶元素,出栈的操作才能访问栈里面的元素
示例:

	stack<int> st2;
	st2.push(5);
	st2.push(6);
	st2.push(7);
	int j;
	int len1 = st2.size();//元素的个数就是要循环的次数
	for (j = 0; j < len1; j++)//这里不能使用st2.size() 因为size 时一直在变化的 
	{
		cout << st2.top() << endl;
		st2.pop();
	}

在这里插入图片描述
或者也可以while判断

	while (st2.size() > 0)
	{
		cout << st2.top()<<endl;
		st2.pop();
	}

queue 队列

一、头文件<queue>

二、逻辑模型

在这里插入图片描述

三、简介

在这里插入图片描述

  1. queue是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端 提取元素。
  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的 成员函数来访问其元素。元素从队尾入队列,从队头出队列。
  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类
    该底层容器应至少支持以下操作:
    empty:检测队列是否为空
    size:返回队列中有效元素的个数
    front:返回队头元素的引用
    back:返回队尾元素的引用
    push_back:在队列尾部入队列
    pop_front:在队列头部出队列
  4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类则使用标准容器deque

四、构造函数

与stack一样queue也只支持构造空的queue对象和拷贝构造queueu对象
queue<T> q; 构造空的queue对象
queue<T> q2(q); 用q拷贝构造q2对象

示例:

queue<int> q;//构造一个空的queue对象
q.push(1);
queue<int> q2(q);//用q拷贝构造q2元素与q中的一样

五、大小、是否为空、插入、删除等操作

函数名称函数说明
bool empty() const检测队列是否为空,是返回true,否则 返回false
size_type size() const返回队列中有效元素的个数
value_type& front()返回队头元素的引用
const value_type& front() const返回队头元素的const引用
value_type& back()返回队尾元素的引用
const value_type& back() const返回队尾元素的cosnt引用
void push(value_type& val)在队尾将元素val入队列
void pop()将队头元素出队列
template <class… Args> void emplace (Args&&… args) (C++11)在队尾构造元素
void swap(queue& x)交换两个队列中的元素

基本的使用方法和使用效果和stack是一样的,可以对其进行参考使用,唯一的就是在访问元素时,访问到的元素就是入队的顺序,而栈的访问可能会与进栈的顺序不同
示例:

	queue < int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	while (q.size() > 0)
	{
		cout << q.front() << endl;
		q.pop();
	}

在这里插入图片描述

实现一个简单栈

使用deque作为底层容器实现
队列只需要将deque的push_back、pop_front、size、empty、front、back调用即可

#include<deque>
#include<iostream>
using namespace std;
template<class T, class Con = deque<T>> //只在deque的一段进行push和pop操作
class Stack 
{
public:    
	Stack() {}//构造函数
    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(); }
	size_t Size()const { return _c.size(); }//返回大小
    bool Empty()const { return _c.empty(); } //是否为空
private:    
	Con _c;
};
void Test()
{
	Stack<int> s;
	s.Push(1);
	s.Pop();
	s.Push(2);
	cout << s.Size() << endl;
}
int main()
{
	Test();
	return 0;
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页