您的位置:首页 > 健康 > 美食 > 山东建筑公司排名_全球装饰公司排名_专业关键词排名软件_高权重网站出售

山东建筑公司排名_全球装饰公司排名_专业关键词排名软件_高权重网站出售

2024/10/30 17:06:29 来源:https://blog.csdn.net/2301_80392199/article/details/143124466  浏览:    关键词:山东建筑公司排名_全球装饰公司排名_专业关键词排名软件_高权重网站出售
山东建筑公司排名_全球装饰公司排名_专业关键词排名软件_高权重网站出售

文章目录

  • 前言
  • 一、适配器模式
    • 概念
    • 分类
  • 二、Stack
    • 核心作用
    • 代码实现
  • 三、Queue
    • 核心作用
    • 代码实现
  • 四、deque双端队列
    • 貌似兼收并蓄?
    • 实则也难以兼得~
  • 总结


前言

  适配器也是STL六大组件之一,请跟我一起领悟它的智慧!
  正文开始!


一、适配器模式

概念

  适配器(配接器)是 STL 中的六大组件之一,扮演着轴承、转换器的角色,使得 STL 中组件的使用更为灵活,比如 栈和队列 就是属于适配器而非容器,以及神秘的反向迭代器也属于适配器

有点像这个
在这里插入图片描述

分类

  我们可以把适配器分为以下三种

 容器适配器 container adapters
 迭代器适配器 iterator adapters
 仿函数适配器 functor adapters

  容器适配器可修改底层指定容器,如由 vector 构成的栈、由 list 构成的队列;迭代器适配器可以实现其他容器的反向迭代器(后续介绍);最后的仿函数适配器就厉害了,几乎可以无限制的创造出各种可能的表达式

在这里插入图片描述

出自侯捷老师的《STL源码剖析》

二、Stack

核心作用

  栈Stack其实是老熟人了,只是这里以另一种视角再次审视它一下

Stack特点是元素特定容器的尾部(即是栈顶)被压入和弹出

在这里插入图片描述
我们可以看到Stack的核心接口有:

  1. empty:判空操作
  2. size:获取元素个数操作
  3. back:获取尾部元素操作
  4. push_back:尾部插入元素操作
  5. pop_back:尾部删除元素操作

并且我们再看第二个模板参数 Container 表示实现栈时用到的底层容器,这里为缺省参数,缺省结构为 双端队列 deque< T >

代码实现

template<class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}bool empty(){return _con.empty();}size_t size(){_con.size();}private:Container _con;};

只要底层容器有我需要的函数接口,那么我就可以为其适配出一个容器适配器

在这里插入图片描述

三、Queue

核心作用

也是老熟人

Queue的最大特点是元素从队尾入队列,从队头出队列

在这里插入图片描述
我们可以看到Queue的核心接口有:

  1. empty:检测队列是否为空
  2. size:返回队列中有效元素的个数
  3. front:返回队头元素的引用
  4. back:返回队尾元素的引用
  5. push_back:返回队尾元素的引用
  6. pop_front:在队列头部出队列

并且我们看到第二个模板参数也为 deque< T >

代码实现

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

在这里插入图片描述

栈和队列都属于特殊的数据结构,原则上是不支持遍历的,因为一旦进行遍历,其中的数据必然被弹出,因此两者都没有提供迭代器

四、deque双端队列

貌似兼收并蓄?

在这里插入图片描述
  我们一看,它好像可以下标访问,也可以进行头部的插入和删除,功能很全面

  我们先要明确,deque(双端队列):是一种双开可口得"连续"空间数据结构

双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度O(1),与vector比较,头插效率高,不需要搬移元素,在扩容时,也不需要搬运大量的数据;与list比较,空间利用率比较高,不需要存储额外的字段

在这里插入图片描述

实则也难以兼得~

马跟驴生下了骡子,有一定的意义,但并不是说骡子完全在继承马跟驴的优点的基础上,完全规避了两者的缺点

  但是deque并不是真的连续的空间,而是由一段连续的小空间拼接而成的,实际上deque类似于一个动态的二维数组,其底层结构如下

在这里插入图片描述
  双端队列底层是一段假象的连续空间,实际是**分段且连续(一个buffer连续,几个buffer分段)**的,为了维护其"整体连续"以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计比较复杂
在这里插入图片描述
  那deque是如何借助其迭代器维护其假想连续的结构呢

在这里插入图片描述

实现下标随机访问的原理

  1. (下标 - 前预留位) / 单个数组长度 获取对应小数组位置
  2. (下标 - 前预留位) % 单个数组长度 获取其在小数组中的对应下标

  不适合遍历,因为在遍历时,deque的迭代器需要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而且在序列场景中,可能需要经常遍历。因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目能看到的一个应用就是,STL用其作为stack和queue的底层数据结构,某种程度上,deque还真的蛮适合的


总结

  感觉如何,是不是被STL的魅力所折服了呢!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com