ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STL——stack与queue详解及模拟实现

2020-11-29 00:00:22  阅读:205  来源: 互联网

标签:deque 容器 STL back queue push stack


STL——stack与queue详解及模拟实现

stack的介绍和使用

stack的文档(官方)

在stl源码中可以看到,stack定义了两个模板参数,一个为类型T,另一个为容器适配器,默认使用deque双端队列来实现。

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

在官方文档也可以看到这个现象。
在这里插入图片描述
deque的实现:指针数组+buffer(缓冲区)

为什么使用deque 而不是用 vector或者list呢?

deque优点:增容代价小,头插头删,尾插尾删效率都为 O(1)
支持随机访问(但效率略低于vector), 对于list 不易产生内存碎片。
缺点 :中间位置的插入删除较繁琐,因此一般仅用于底层容器。

stack:需要的是尾插尾删,不会用到随机访问,虽然vector也可以完成,但是vector需要频繁的增容,进而拷贝元素,因此deque是很好的选择。

在这里插入图片描述

stack的实现

stack的实现比较简单,只需要使用deque作为底层容器。
成员包含需要使用的容器即可,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<deque>

using namespace std;

template<class T,class Container=deque<T>>
class Stack
{
public:
	void push(const T& x)// 入栈
	{
		_v.push_back(x);
	}
	void pop()//出栈
	{
		_v.pop_back();
	}
	T& top()//栈顶元素
	{
		return _v.back();
	}
	bool empty()
	{
		return _v.empty();
	}
private:
	Container _v;
};

一般使用方法,给出了一个简单的测试用例。
注意这里,可以自定义指定容器传入的参数,默认为deque。

void test1()
{
	//Stack<char, vector<char>> s;
	Stack<char> s;
	s.push('1');
	s.push('2');
	s.push('3');
	s.push('4');
	s.push('5');
	while (!s.empty())
	{
		cout << s.top() << " ";
		s.pop();
	}
	cout << endl;
}

int main()
{
	test1();
	return 0;
}

后进先出,输出结果如下:
在这里插入图片描述

queue的介绍和使用

在stl源码中可以看到,与stack一样,queue定义了两个模板参数,一个为类型T,另一个为容器适配器,默认使用deque双端队列来实现。

template <class T, class Container = deque<T> > class queue;

queue的文档(官方)

其底层容器需要包含以下接口
在这里插入图片描述

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

queue的底层容器可以为list,deque。
那为什么不用list呢?

list 容易产生内存碎片,deque的空间利用率更高。
之所以vector不行,原因是vector 不支持pop_front()接口 ,因为queue要实现头删(出队)的操作。

函数说明:
在这里插入图片描述

queue的实现

与stack一样,实现也比较简单,使用容器适配器。

#define _CRT_SECURE_NO_WARNINGS 1

#include<list>
#include<queue>
#include<deque>
#include<iostream>

using namespace std;

template<class T,class Container=deque<T>>
class Queue
{
public:
	void push(const T& x) //入队
	{
		lst.push_back(x);
	}
	void pop()//出队
	{
		lst.pop_front();
	}
	T& front()//队头
	{
		return lst.front();
	}
	T& back()
	{
		return lst.back();
	}
	bool empty()
	{
		return lst.empty();
	}
	size_t size() 
	{
		return lst.size();
	}
private:
	Container lst;
};

默认使用deque,也可自己传入list的参数。
一般这样使用。如下:

int main()
{
//	Queue<int ,list<int>> q;
	Queue<int > q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);
	while (!q.empty())
	{
		cout << q.front();
		q.pop();
	}
}

queue遵循先进先出,所以结果如下:
在这里插入图片描述

标签:deque,容器,STL,back,queue,push,stack
来源: https://blog.csdn.net/weixin_51582527/article/details/110296013

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有