C++——Stack&&Queue

这篇具有很好参考价值的文章主要介绍了C++——Stack&&Queue。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一Stack

1介绍

2接口 

3模拟实现

4栈的oj题

 二Queue

1介绍

2接口

3模拟实现

三容器适配器

1再谈栈和队列 

四优先级队列

1接口

​编辑

2仿函数

五dequeue的简单介绍 


一Stack

1介绍

先来看看库中对栈的介绍:

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

C++——Stack&&Queue,C++,c++

2接口 

bool empty() const;   判断栈中是否为空
size_type size() const;   返回栈中元素的个数
value_type& top();        返回栈顶的元素
void push (const value_type& val);   往栈中压入val
void pop();    删除栈顶元素

3模拟实现

从栈的接口中可以看出,栈实际是一种特殊的vector,因此使用vector完全可以模拟实现stack。

#include<vector>
namespace bite
{
	template<class T>
	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:
		std::vector<T> _c;
    }
}

4栈的oj题

1 最小栈
2 栈的压入、弹出序列

3 逆波兰表达式求值

1 最小栈

 二Queue

1介绍

1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素:元素从队尾入队列,从队头出队列
3. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

2接口

 文章来源地址https://www.toymoban.com/news/detail-850104.html

bool empty() const;         判断队列中是否为空
size_type size() const;     返回队列中的个数
value_type& front();        返回队头元素
value_type& back();         返回队尾元素
void push (const value_type& val);     在队尾中插入元素
void pop();                 删除队头元素

3模拟实现

因为queue的接口中存在头删和尾插,因此使用vector来封装效率太低,故可以借助list来模拟实现

#include <list>
namespace bite
{
	template<class T>
	class queue
	{
	public:
		queue() {}
		void push(const T& x) { _c.push_back(x); }
		void pop() { _c.pop_front(); }
		T& back() { return _c.back(); }
		const T& back()const { return _c.back(); }
		T& front() { return _c.front(); }
		const T& front()const { return _c.front(); }
		size_t size()const { return _c.size(); }
		bool empty()const { return _c.empty(); }
	private:
		std::list<T> _c;
    }
}

三容器适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口
 C++——Stack&&Queue,C++,c++

1再谈栈和队列 

 虽然栈和队列也可以存储元素,但在stl中没有把它们划分在容器行列里,而是将它们叫做容器适配器,它们的实现是通过别的容器来实现的:实现的模板中传入了容器参数

以栈为例:

C++——Stack&&Queue,C++,c++

按照上面来完善stack的模拟实现: 

template<class T,class Container = deque<T>>//库中给出的缺省值是deque<T>
class Stack
{
public:
	bool empty()
	{
		return _v.empty();
	}
	size_t size()
	{
		return _v.size();
	}
	const T& top()
	{
		return _v.back();
	}
	void push(const T& x)
	{
		_v.push_back(x);
	}
	void pop()
	{
		_v.pop_back();
	}
private:
	Container _v;
};

知道了这一点,我们在使用stack时想用那个容器来实现都可以~

四优先级队列

1使用优先级队列与队列一样,需要在前面包含#incldue<queue>才能使用

2优先级队列里面的排序是(默认)以大堆的排序来实现的vector类型的队列

3需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

1接口

bool empty() const;                   判断是否为空
size_type size() const;               返回个数
const value_type& top() const;        返回队头元素 
void push (const value_type& val);    队尾插入元素
void pop();                            删除队头元素

 使用这些接口:

C++——Stack&&Queue,C++,c++

我们发现:打印出来的顺序是降序的:我们在堆排序中说了:建大堆是排升序的。这里这么是反过来的??   

这里是在学习中最容易遇到坑的地方;在底层实现的思路:

将数据建大堆,第一个一定是数组中最大的,先把它打印出来;在删除pop时,先把第一个与最后一个交换位置,再进行pop删除最后一个元素——也就是最大的那一个;最后调整数组为大堆...与我们实现堆排序的思想不同!!

 如果我们想让它打印出来是升序呢?

在模板中传类型:

 C++——Stack&&Queue,C++,c++

C++——Stack&&Queue,C++,c++

和sort传入的greator<int>进行比较:

C++——Stack&&Queue,C++,c++

2仿函数

在类中重载()的方式就叫做仿函数;

C++——Stack&&Queue,C++,c++

上面sort参数中传入greater<int>() 对象与这里是类似的:

3模拟实现

模拟实现优先级队列时可以写仿函数来控制升序降序:

//适配器进行容器调用
namespace bit
{
	template<class T,class Container = deque<T>>
	class Stack
	{
	public:
		bool empty()
		{
			return _v.empty();
		}
		size_t size()
		{
			return _v.size();
		}
		const T& top()
		{
			return _v.back();
		}
		void push(const T& x)
		{
			_v.push_back(x);
		}
		void pop()
		{
			_v.pop_back();
		}
	private:
		Container _v;
	};
	
	template<class T, class Container = deque<T>>
	class Queue
	{
	public:
		bool empty()
		{
			return _l.empty();
		}
		size_t size()
		{
			return _l.size();
		}
		const T& front()
		{
			return _l.front();
		}
		const T& back()
		{
			return _l.back();
		}
		void push(const T& x)
		{
			_l.push_back(x);
		}
		void pop()
		{
			_l.pop_front();
		}
	private:
		Container _l;
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& x,const T& y)
		{
			return x > y;
		}
	};

	template<class T>
	class less
	{
	public:
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};

	template<class T,class Container=vector<T>,class Compare = less<T>>
	class priority_queue
	{
	public:
		bool empty() const
		{
			return _pro.empty();
		}

		size_t size() const
		{
			return _pro.size();
		}

		const T& top() const
		{
			return _pro[0];
		}
		//less -> 降序 -> 建大堆(与HeapSort的逻辑不同)
		void AjustUp(size_t child)
		{
			Compare com;
			size_t parent = (child - 1) / 2;
			while (child >0)
			{
				     //_pro[parent] < _pro[child]
				if (com(_pro[parent] , _pro[child]))
				{
					swap(_pro[child], _pro[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

		void push(const T& val)
		{
			_pro.push_back(val);
			AjustUp(_pro.size()-1);
		}

		void AjustDown(size_t parent)
		{
			Compare com;
			size_t child = parent * 2 + 1;
			while (child < _pro.size())
			{
				//选最大(降序)的child与parent交换 _pro[child] <  _pro[child + 1]          
				if (child + 1<_pro.size() && com(_pro[child] , _pro[child+1]))
				{
					child++;
				}
				//      _pro[parent] < _pro[child]
				if (com(_pro[parent] , _pro[child]))
				{
					swap(_pro[child], _pro[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			swap(_pro[0], _pro[_pro.size() - 1]);
			_pro.pop_back();
			AjustDown(0);
		}	
	private:
		Container _pro;

	};

 C++——Stack&&Queue,C++,c++

五dequeue的简单介绍 

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高

在它的接口中,既有list的,也有vector的:可以说,dequeue=vector+list

C++——Stack&&Queue,C++,c++

C++——Stack&&Queue,C++,c++

但deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组:

C++——Stack&&Queue,C++,c++

C++——Stack&&Queue,C++,c++
 

那dequeue具体是怎么样来访问元素的呢? 

底层用迭代器,迭代器中嵌套这迭代器来进行对数据的管理:

C++——Stack&&Queue,C++,c++ 

dequeue插入删除效果好,又是一段’连续的数组‘,在stl中stack与queue的默认容器都选择它来给缺省值,但它也不是完美的:

如果在实践中,要在中间插入一个数据时,怎么办??

它有两个解决方法:要么在这段数组中在开辟空间来存储;要么移动后面的数据来进行插入;不管是哪一种,效果都不好!

总结:在要用到[ ]访问时不建议用dequeue而选择vector或者list!!

 以上便是我的学习整理,有错误欢迎在评论区里指出,感谢您的观看!!

 

 

到了这里,关于C++——Stack&&Queue的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】开始使用stack 与 queue

    送给大家一句话: 忍受现实给予我们的苦难和幸福,无聊和平庸。 – 余华 《活着》 在之前的学习中,我们已经对 STL 模板中的 string list vector 等容器进行了详细的探讨,从而获得了对这些容器操作的清晰理解。基于这些知识,现在转向学习 stack(栈) 和 queue(队列)就显得

    2024年04月23日
    浏览(21)
  • C++ STL--->stack和queue

    stack文档 stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行 元素的插入与提取操作。 stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定 的成员函数来访问其元素,将特定类作为

    2024年01月16日
    浏览(35)
  • 【C++】stack、queue模拟实现+仿函数

    铁汁们,今天给大家分享一篇stack、queue模拟实现+仿函数,来吧,开造⛳️ stack是容器适配器,专门用于进行”先进后出”操作的环境中,只能在容器的一端进行数据的插入和删除操作,元素在特定容器的尾部(即栈顶)被压入和弹出。 容器适配器是将特定的类进行封装,将其

    2024年03月19日
    浏览(32)
  • C++的stack和queue+优先队列

    适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 stack和queue都是容器适配器,底层都是通过去适配双端队列deque去实现的,STL中没有把stack和queue划分在容

    2024年02月13日
    浏览(21)
  • C++:Stack和Queue的模拟实现

                                                        创作不易,感谢三连!          适配器是一种设计模式 (设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结), 该种模式是将一个类的接口转换成客户希望的另外一个接口。    

    2024年03月12日
    浏览(29)
  • 【C++】stack与queue的模拟实现

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 stack与queue的实现比较简单,本篇不会有太大的篇幅,但值得我们学习的是『 适配器

    2024年01月24日
    浏览(34)
  • [C++随笔录] stack && queue模拟实现

    🗨️stack的容器适配器应该选什么比较好呢? 首先, stack的特点是 头部入, 尾部出 ⇒ 尾插 和 尾删操作比较频繁 我们前面学过的容器有 vector 和 list, vector 和 list的尾插 和 尾删的时间复杂度是 O(1) , 还是适合做容器适配器的. stack的基本结构 用这个容器对象来进行模拟实现stac

    2024年02月06日
    浏览(31)
  • 【C++杂货铺】详解 stack 和 queue

            欢迎收看本期【C++杂货铺】,本期内容将讲解C++STL中stack和queue的内容,其中包含了stack , queue,priority_queue是什么,怎么使用以及模拟实现这些容器。         此外,还将将讲解设计模式中的适配器模式,以及STL中stack,queue的底层deque。         stack是一种容器适配

    2024年04月12日
    浏览(20)
  • 【C++干货铺】适配器 | stack | queue

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列学习专栏: C++干货铺 代码仓库: Gitee ========================================================================= 目录 stack的介绍和使用 stack的介绍 stack的使用 queue的介绍和使用 queue的介绍 qu

    2024年02月05日
    浏览(36)
  • C++ deque/queue/stack的底层原理

    和 vector 容器采用连续的线性空间不同,deque 容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域。 deque采用一块所谓的map数组(注意,不是STL的map容器)作为主控。 这里所谓map是一小块连续空间 (类似于ve

    2024年02月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包