C++ 9 stack_queue:数据结构的核心奥秘

stack

栈(Stack)是一种运算受限的线性表 ,只允许在一端进行插入或删除操作。这一端被称为栈顶 (Top),相对地,另一端称为栈底 (Bottom)。栈的特点是后进先出(Last In First Out,简称LIFO),即最后插入的元素最先被删除。

基本操作

  • push(): 在栈顶添加一个元素。
  • pop(): 移除栈顶元素。
  • top(): 返回栈顶元素的引用,但不移除它。
  • empty(): 检查栈是否为空。
  • size(): 返回栈中元素的数量。
cpp 复制代码
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.pop();
cout<<st.top();
st.empty();
cout<<st.size();

模拟实现

cpp 复制代码
#pragma once
namespace Milestone
{
	template<class T,class Container = vector<int>>//给缺省值
	class stack {
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		const T& Top()const
		{
			return _con.back();
		}
		size_t size()const
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

queue

它允许在一端添加元素(称为队尾),并在另一端移除元素(称为队首)。

队列是一种线性数据结构,它遵循以下规则:

  • 元素只能从队尾添加。
  • 元素只能从队首移除。

基本操作

  • empty(): 检查队列是否为空。
  • size(): 返回队列中的元素数量。
  • front(): 返回队首元素的引用。
  • back(): 返回队尾元素的引用。
  • push(): 在队尾添加一个元素。
  • pop(): 移除队首元素。
cpp 复制代码
queue<int> st;
queue.push(1);
queue.push(2);
queue.push(3);
queue.pop();
cout<<queue.front();
cout<<queue.back();
queue.empty();
cout<<queue.size();

模拟实现

cpp 复制代码
#pragma once

namespace Milestone {
	template<class T,class Container = list<int>>
	class queue {
	public:
		void push(const T& x)
		{
			_con.push(x);
		}
		void pop()
		{
			_con.pop();
		}
		bool empty()
		{
			return _con.empty();
		}
		size_t size()
		{
			return _con.size();
		}
		T& front()const
		{
			return _con.front();
		}
		T& back()const
		{
			return _con.back();
		}
	private:
		Container _con;
	};
}

priority_queue

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素
    中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶
    部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue
    提供一组特定的成员函数来访问其元素。元素从特定容器的"尾部"弹出,其称为优先队列的
    顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过
    随机访问迭代器访问

基本操作

empty():检测容器是否为空
size():返回容器中有效元素个数
front():返回容器中第一个元素的引用
push_back():在容器尾部插入元素
pop_back():删除容器尾部元素

cpp 复制代码
priority_queue<int> pq;
pq.push(1);
pq.push(2);
pq.empty();
pq.pop();
cout<<pq.top();

模拟实现

cpp 复制代码
#pragma once
namespace Milestone
{
	//默认是大堆
	template<class T,class Container = vector<T>>
	class priority_queue {
	public:
		void adjustup(size_t child)//有隐式this
		{
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
			}
		}
		void push(const T& x)
		{
			_con.push_back(x);
			adjustup(_con.size() - 1);
		}
		void adjustdown(size_t parent)
		{
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && _con[child + 1] > _con[child])
					++child;
				if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					break;
			}
		}
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjustdown(0);
		}
		const T& top()
		{
			return _con[0];
		}
		size_t size()const
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

容器适配器

什么是容器适配器

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

stack:栈适配器
queue:队列适配器
priority_queue:优先队列适配器
在上述中,stack与queue均选择deque为默认容器

为什么选择deque

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

  1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进
    行操作。
  2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的
    元素增长时,deque不仅效率高,而且内存使用率高。

vector list deque的优缺点

vector

Vecaor

优点;

1.尾插尾删效率高,支持下标随机访问

2.物理空间连续,所以高速缓存利用率高

缺点:

1.空间需要扩容,扩容有代价(效率和空间)

2.头部和中间插入数据慢

list

优点:

1.按需申请空间,不需要释放空间

2.任意位置插入删除

缺点

1.不支持下标随机访问

deque

优点

1.头插尾插插入效率比vector和list高

2.下标随机访问不错,但相比vector逊

缺点:

1中间插入删除效率低,要挪动数据,为O(N)

相关推荐
csbysj20203 小时前
JavaScript AI 编程助手
开发语言
t198751283 小时前
基于MATLAB的线性判别分析(LDA)降维算法实现方案
开发语言·算法·matlab
weixin_462446233 小时前
nodejs 下使用 Prettier 美化单个 JS 文件(完整教程)
开发语言·javascript·ecmascript
醇氧3 小时前
【Windows】从守护到终结:解析一个 Java 服务的优雅停止脚本
java·开发语言·windows
努力发光的程序员3 小时前
互联网大厂Java求职面试实录
java·jvm·线程池·多线程·hashmap·juc·arraylist
reasonsummer3 小时前
【办公类-18-07】20251215(Python)“口腔检查涂氟信息”批量生成打印(区名、学号、姓名、学校、班级、身份证、户籍、性别、民族)
开发语言·python
小鹿学程序3 小时前
FileZilla连接到虚拟机
java·服务器·开发语言
仰泳的熊猫3 小时前
1108 Finding Average
数据结构·c++·算法·pat考试
Haooog3 小时前
Docker面试题(不定时更新)
java·docker·面试