C++入门篇10---stack+queue+priority_queue

news2024/11/16 20:33:50

前言

本文主要是介绍C++库中的栈、队列和优先级队列(其实就是堆)的一些接口以及如何用C++来实现它们,对这三种数据结构就不多介绍了,如有不了解的同学,请查阅我之前写的两篇博客

  • 栈和队列的实现
  • 二叉树和堆详解

下面正片开始

一、stack

1.了解stack的相关接口

函数名称接口说明
empty()查看栈是否为空
size()查看栈中的元素个数
push()将元素压入栈中
pop()从栈顶删除元素
top()返回栈顶元素
stack()构造空栈
void test1()
{
	//后进先出
	stack<int>st;
	st.push(1);
	st.push(3);
	st.push(4);
	st.push(2);
	while (st.size())
	{
		cout << st.top() << endl;
		st.pop();
	}
}

2.stack的实现

//这里统一说明一下,栈、队列、优先级队列都是适配器容器,不是容器
//所谓的适配器容器就是对其他容器的接口进行包装,改造实现的
//我们往下看就会发现,stack的实现基本上都是在调用其他容器的函数
//其实我们在学数据结构的时候,就已经发现栈既可以用数组实现,也能用链表实现
//本质就是因为数组和链表两种数据结构的功能都符合stack的需求,这里也是一样
//stack不关心它用的什么容器实现,它只关心该容器是否有它需要的功能函数
//同时这里也体现了C++库的发明人的智慧,所有容器的功能相同的函数名称基本都一样(可谓妙绝,请细品)
namespace zxws {
    //deque是双端队列---该容器的底层实现以后有机会再讲,各位可以去看一眼deque的文档,
    //它也支持下面的几个函数,同时它的底层实现和stack最搭配,所以库里的stack默认用它实现
	template<class T, class Container = deque<T>>
	class Stack {
	private:
		Container _con;
	public:
		T& top() {
			return _con.back();
		}
		const T& top() const{
			return _con.back();
		}
		void pop() {
			_con.pop_back();
		}
		void push(const T& val) {
			_con.push_back(val);
		}
		size_t size() const{
			return _con.size();
		}
		bool empty() {
			return _con.empty();
		}
	};
}

二、queue

1.了解queue的相关接口

函数声明接口说明
empty()判断队列是否为空
size()查看队列中的元素个数
push()向队列中插入元素
pop()从队头删除元素
front()返回队头元素
back()返回队尾元素
queue()构造空队列

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

 2.queue的实现

namespace zxws {
	template<class T,class Container = deque<T>>
    //deque的底层实现和queue最搭配,所以库里的queue默认用它实现
    //当然这并不是说deque就比vector、list更好,只是各有各的适用场景
	class Queue {
	private:
		Container _con;
	public:
		T& front() {
			return _con.front();
		}
		T& back() {
			return _con.back();
		}
		const T& front() const {
			return _con.front();
		}
		const T& back() const {
			return _con.back();
		}
		void pop() {
			_con.pop_front();
		}
		void push(const T& val) {
			_con.push_back(val);
		}
		size_t size() {
			return _con.size();
		}
		bool empty() {
			return _con.empty();
		}
	};
}

三、priority_queue(优先级队列)---堆(heap)

1.了解priority_queue的相关接口

函数声明接口说明
priority_queue()/priority_queue(first,last)构造一个空的优先级队列/用一段迭代器区间初始化
empty()查看优先级队列是否为空
size()返回优先级队列中的元素个数
push()向优先级队列中插入元素
top()返回优先级队列中的最大/最小元素,即堆顶元素
pop()删除优先级队列中的最大/最小元素,即堆顶元素
void test3()
{
	priority_queue<int>q;//默认大堆
	//priority_queue<int, vector<int>, greater<int>>q;//小堆
	//这里后面的实现中会讲到
	q.push(1);
	q.push(3);
	q.push(4);
	q.push(2);
	while (q.size())
	{
		cout << q.top() << endl;
		q.pop();
	}
}

 2.priority_queue的实现

namespace zxws
{
    template <class T, class Container = vector<T>, class Compare = less<T> >
    class priority_queue
    {
    public:

        priority_queue(){}
        void AdjustDown(int parent) 
        {
            int n = c.size();
            for (int child = parent * 2 + 1; child < n; parent = child, child = parent * 2 + 1)
            {
                if (child + 1 < n && comp(c[child],c[child+1]))
                    child++;
                if (comp(c[parent], c[child]))
                    swap(c[parent], c[child]);
                else
                    break;
            }
        }

        void AdjustUp(int child)
        {
            for (int parent = (child - 1) / 2; child > 0; child = parent, parent = (child - 1) / 2)
            {
                if (comp(c[parent], c[child]))
                    swap(c[parent], c[child]);
                else
                    break;
            }
        }

        template <class InputIterator>
        priority_queue(InputIterator first, InputIterator last)
            :c(first,last)
        {
            for (int i = (c.size() - 1 - 1) / 2; i >= 0; i--)
                AdjustDown(i);
        }

        bool empty() const
        {
            return c.empty();
        }

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

        const T& top() const
        {
            return c[0];
        }

        void push(const T& x)
        {
            c.push_back(x);
            AdjustUp(c.size() - 1);
        }

        void pop()
        {
            swap(c.back(), c[0]);
            c.pop_back();
            AdjustDown(0);
        }

    private:
        Container c;
        Compare comp;
    };
};

(上面priority_queue的实现的第三个模板参数其实是仿函数,有兴趣的可以去查查什么是仿函数)

四、补充---简单说明一下deque

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

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,给张图,让大家简单了解一下

deque的优缺点

  • 与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。
  • 与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。
  • 但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构

 思考:大家可以结合deque的优点想想为什么stack和queue底层的默认容器是deque?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1047638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业知识库构建:关于企业知识库及知识平台搭建的重要性!

随着企业规模的不断发展与壮大&#xff0c;在企业运营相关知识信息将不断产生&#xff0c;而知识处理中&#xff0c;建立知识库会面临着信息零散碎片化、信息关系复杂难梳理、信息不完整、碎片数据难以沉淀存储等问题…… 所以作为企业管理者&#xff0c;首先需要意识到关于企业…

SPA项目之主页面--数据表格的增删改查

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于VueElementUI的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.增删改查 1.样式准备 2.编码 …

聚合统一,SpringBoot实现全局响应和全局异常处理

目录 前言 全局响应 数据规范 状态码(错误码) 全局响应类 使用 优化 全局异常处理 为什么需要全局异常处理 业务异常类 全局捕获 使用 优化 总结 前言 在悦享校园1.0版本中的数据返回采用了以Map对象返回的方式&#xff0c;虽然较为便捷但也带来一些问题。一是在…

机器人制作开源方案 | 货物输送小车

作者&#xff1a;周展鹏 黄万森 彭军铭 吕会权 聂文俊 单位&#xff1a;柳州工学院 指导老师&#xff1a;蔡洪炜 王一波 1. 场景调研 目前货物输送已成为人们生活中必不可少的部分&#xff0c;加之国内近年来有因快递配送导致疫情迅速传播的事件常有发生&#xff0c;因此在疫…

Mybatis3详解 之 全局配置文件详解

1、全局配置文件 前面我们看到的Mybatis全局文件并没有全部列举出来&#xff0c;所以这一章我们来详细的介绍一遍&#xff0c;Mybatis的全局配置文件并不是很复杂&#xff0c;它的所有元素和代码如下所示&#xff1a; <?xml version"1.0" encoding"UTF-8&…

精通Linux系列第二章:虚拟机安装Linux系统环境教程

文章目录 一、前言二、VMware Fusion安装教程2.1 说说安装虚拟机的好处2.2 安装VMware Fusion 三、环境搭建3.1 各种Linux发行版介绍与iso下载链接3.2 VMware Fusion安装Linux3.2.1 Ubuntu桌面版安装3.2.2 Debian桌面版安装3.2.3 Fedora桌面版安装3.2.4 CentOS桌面版安装3.2.5 …

RHCA礼品领取步骤

RHCA礼品领取步骤 1. 进入领取页面 考过RHCA的5门课程后会收到5份单科1份RHCA电子证书.其实还有一份玻璃证书笔记本A面贴纸红帽ID号短袖T恤可以领取. 领取地址如下: http://redhat.brandfuel.com 在第一框内填写红帽ID就是考试时填写的9位id号,每3位用-分割 第二个框填写姓,就…

图扑软件受邀亮相 IOTE 2023 国际物联网展

IOTE 2023 国际物联网展&#xff0c;作为全球物联网领域的盛会&#xff0c;于 9 月 20 日 - 22 日在中国深圳拉开帷幕。本届展会以“IoT构建数字经济底座”为主题&#xff0c;由深圳市物联网产业协会主办&#xff0c;打造当前物联网最新科技大秀。促进物联网与各行业深度融合&a…

Android studio “Layout Inspector“工具在Android14 userdebug设备无法正常使用

背景描述 做rom开发的都知道&#xff0c;“Layout Inspector”和“Attach Debugger to Android Process”是studio里很好用的工具&#xff0c;可以用来查看布局、调试系统进程&#xff08;比如setting、launcher、systemui&#xff09;。 问题描述 最进刚开始一个Android 14…

海贝造音强势登陆深圳 助力本土原创音乐升阶

海贝负责人&#xff1a;萧弘天先生 据媒体报导&#xff0c;全球音乐产业收入已恢复至疫情前水平&#xff0c;甚至比往年高出16%&#xff0c;值此佳机&#xff0c;在大湾区深耕娱乐行业30年之久的一众行业先锋&#xff0c;港澳资深传媒人在深圳成立了海贝造音。 深圳&#xff…

RFID资产管理系统应用助力企业实现高效资产运营管理

在企业运营中&#xff0c;资产以各种形式存在&#xff0c;包括生产物资、设备、车辆、办公桌、电脑、电缆等等&#xff0c;这些资产都具有价值高、流动性强、安全管理难等特点&#xff0c;而固定资产数量多、种类繁多、价值高、使用周期长、使用地点分散等特点使得其管理变得非…

增值税发票的Python代码快速识别

# 导入potencent这个库&#xff0c;下载命令&#xff1a;pip install potencent import potencent # 调用增值税识别的功能 potencent.ocr.VatInvoiceOCR(img_pathrC:\vx_CoderWanFeng\your_img.jpg)

你的游戏项目有这些问题吗?

在移动游戏对高品质画面的要求不断增加的背景下&#xff0c;我们一直专注于移动设备GPU性能的优化&#xff0c;以确保您的游戏体验得以最佳展现。然而&#xff0c;不同GPU芯片之间的性能差异以及由此可能引发的GPU瓶颈问题使得优化工作更加具有挑战性。 因此&#xff0c;在不久…

GM(1,1)应用案例1

北方某城市1986-1992年道路交通平均噪声级数数据如表&#xff08;1&#xff09;建立GM(1,1)模型。 表&#xff08;1&#xff09;城市交通平均噪声级数数据/db(A) 编号 1 2 3 4 5 6 7 年份 1986 1987 1988 1989 1990 1991 1992 Leq 71.1 72.4 72.4 72.1 7…

安卓:解决AndroidStudio导出Unity的Apk(APP)出现2个显示图标

用AndroidStudio打开该项目 实现只保留1个app图标 AndroidManifest.xml的改法如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android" package"com.fru…

26055-2022 再生碳化钨粉 思维导图

声明 本文是学习GB-T 26055-2022 再生碳化钨粉. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了再生碳化钨粉的分类、技术要求、试验方法、检验规则、标志、包装、运输、贮存、随行文 件及订货单内容。 本文件适用于以回收的硬…

C# 多态性

简单来讲&#xff0c;多态&#xff0c;就是派生类的对象可以隐式转化为基类对象。在派生类中可以重写基类中定义并实现的虚方法。 可以用基类声明&#xff0c;用派生类实例化&#xff0c;这样的变量调用方法时会调用运行时方法&#xff08;即派生类重写的方法&#xff09;。 …

基于Vue和Element UI实现前后端分离和交互

目录 前言 一、Element UI简介 1.Element UI是什么 2.Element UI的特点 二、项目搭建 1.创建一个SPA项目 2.安装 Element-UI 3.导入组件 4.创建登陆注册界面 登录组件---Login.vue 注册组件---Register.vue 定义组件与路由的对应关系 效果演示&#xff1a; 三、前…

激活函数总结(四十六):激活函数补充(Nipuna、StarReLU)

激活函数总结&#xff08;四十六&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Nipuna激活函数2.2 StarReLU激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、Swish、ELU、SELU、GELU、Softmax、…

Ros2 学习01-Ros2 VS Ros1

ROS最早的设计目标就是开发这样一款PR2家庭服务机器人&#xff0c;这款机器人绝大部分时间都是独立工作&#xff0c;为了让他具备充足的能力&#xff1a; 它搭载了工作站级别的计算平台和各种先进的通信设备&#xff0c;不用担忧算力不够&#xff0c;有足够的实力支持各种复杂…