高效利用队列的空间

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

  大家都知道队列是可以用数组来模拟的,可以先开辟一段定长的数组空间,然后分别使用两个变量head和tail来代指队列的头和尾,从而维护整个队列,相信到这里大家都比较熟悉。不过这种做法是有弊端的,比如说下图这种情况

高效利用队列的空间

  假设经过不断地增删元素,Head和Tail已经来到了数组最后两个位置,这时候整个队列中只有两个元素,并且我们也不能再增加元素了,因为已经到达了容量的上限。然而,这时候前面一大片连续空间就造成了浪费。因此我们重新设想一下

高效利用队列的空间

  这是另外一种构思,此时队列当中存有三个元素,那么该怎么实现呢?

#define MAXSIZE (1 << 16)

template <typename _Tp>
struct fifo {
	uint16_t front = 1;
	uint16_t end = 1;
	int frontCount = -0x3f3f3f3f;
	int endCount = -0x3f3f3f3f;

	_Tp arr[MAXSIZE];
}

  对于front和end两个变量,可以用无符号整型来实现,当无符号整型溢出的时候,会自然的变成0,问题就爽快的解决了。不过这里还引入了两个变量,frontCount和endCount,这是为了判断front是在end的前面还是后面。换句话说,当end发生溢出的时候,end就来到了front前面,这时候endCount就加1,frontCount同理。

 

    bool empty() {
		if (endCount > frontCount)
			return false;
		
		return (front == end) ? true : false;
	}

	bool full() {
		if (endCount > frontCount && end == front)
			return true;

		return false;
	}

	std::size_t size() {
		if (full())
			return MAXSIZE;
		else if (empty())
			return 0;
		else if (frontCount == endCount)
			return (end - front);
		else 
			return (MAXSIZE - front + end);
	}

  以上是判断队列容量的一些相关成员函数,实现都比较简略,较为关键的是入队和出队的操作实现。

    void push(_Tp&& element) {
		if (full()) {
			std::cerr << "Full\n";
			return;
		}

		if (((uint16_t) (end + 1)) == 0)
			++endCount;

		arr[++end] = element;
	}

	void push(const _Tp& element) {
		if (full()) {
			std::cerr << "Full\n";
			return;
		}

		if (((uint16_t) (end + 1)) == 0)
			++endCount;

		arr[++end] = element;
	}

	std::optional<_Tp> pop() {
		if (empty()) 
			return std::nullopt;

		if (((uint16_t) (front + 1)) == 0)
			++frontCount;

		return arr[++front];
	}

  有个小区别,这里的front指向的位置在逻辑上是不存储元素的,其它的和开篇所讲的都差不多。那么,对于(end + 1) ,为什么要加一个强制转换呢?因为如果不加的话,end和1进行运算之后就提升为了int类型,这时候结果是int类型的,它不会因为溢出而变成0。

  完整代码:

#include <iostream>
#include <cstdint>
#include <optional>

#define MAXSIZE (1 << 16)

template <typename _Tp>
struct fifo {
	uint16_t front = 1;
	uint16_t end = 1;
	int frontCount = -0x3f3f3f3f;
	int endCount = -0x3f3f3f3f;

	_Tp arr[MAXSIZE];

	void push(_Tp&& element) {
		if (full()) {
			std::cerr << "Full\n";
			return;
		}

		if (((uint16_t) (end + 1)) == 0)
			++endCount;

		arr[++end] = element;
	}

	void push(const _Tp& element) {
		if (full()) {
			std::cerr << "Full\n";
			return;
		}

		if (((uint16_t) (end + 1)) == 0)
			++endCount;

		arr[++end] = element;
	}

	std::optional<_Tp> pop() {
		if (empty()) 
			return std::nullopt;

		if (((uint16_t) (front + 1)) == 0)
			++frontCount;

		return arr[++front];
	}

	bool empty() {
		if (endCount > frontCount)
			return false;
		
		return (front == end) ? true : false;
	}

	bool full() {
		if (endCount > frontCount && end == front)
			return true;

		return false;
	}

	std::size_t size() {
		if (full())
			return MAXSIZE;
		else if (empty())
			return 0;
		else if (frontCount == endCount)
			return (end - front);
		else 
			return (MAXSIZE - front + end);
	}
};

  相信看完本篇,你也多多少少有收获,喜欢的可以动动手指点赞加关注!  文章来源地址https://www.toymoban.com/news/detail-746175.html

到了这里,关于高效利用队列的空间的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 经实测利用POSTMAN根本无法进行并发测试,大家不要再被一些搬运工给误导了

    以下为我的实测记录 一、先上我测试的接口代码,就是一个redis的tryLock分布式锁的获取,接口在获取到锁后,线程sleep了5秒,此时线程是不释放锁的,那按道理第二个请求在这个时间进来,是获取不到锁的,但结果却不是这样的 二、按照网上的那些博文,postman操作步骤如下

    2024年02月11日
    浏览(48)
  • 快来,别人不知道的秘密,QQ空间视频下载教程

    打开自己的QQ空间,进入视频界面 先按F12跳出,浏览器调试工具   点击XHR,输入框输入”video_get_data“,然后点击你想要下载的视频得到一个链接地址  点击链接,再点解Preview,找到如图所示的url,复制它的链接 打开一个新的窗口,输入复制的链接,如图所示 鼠标放入视频位置

    2024年02月12日
    浏览(82)
  • 【人工智能概论】 构建神经网络——以用InceptionNet解决MNIST任务为例

    两条原则,四个步骤。 从宏观到微观 把握数据形状 准备数据 构建模型 确定优化策略 完善训练与测试代码 InceptionNet的设计思路是通过增加网络宽度来获得更好的模型性能。 其核心在于基本单元Inception结构块,如下图: 通过纵向堆叠Inception块构建完整网络。 MNIST是入门级的

    2023年04月20日
    浏览(53)
  • Visual Studio 2022 程序员必须知道高效调试手段与技巧(上)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,前面给大家介绍了Visual Studio 2022 下载与安装今天我们就来介绍一下 VS2022 最强大的功能调试?    ⛳️ 调试可以说是一个

    2024年02月15日
    浏览(40)
  • Visual Studio 2022 程序员必须知道高效调试手段与技巧(中)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,上一章给大家介绍了 Visual Studio 2022 快捷键和 版本介绍,今天就来给大家来点干货    ⛳️ 今天来正式来调试环节,带大

    2024年02月15日
    浏览(53)
  • Visual Studio 2022 程序员必须知道高效调试手段与技巧(下)终章

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,上一章给大家介绍了 Visual Studio 2022功能使用,和一些常用快捷键!    ⛳️ 今天来正式来调试环节,带大家看看程序出

    2024年02月15日
    浏览(58)
  • 告诉你如何从keil工程知道使用了多少RAM和ROM空间

    我们常常在使用一款芯片的时候往往都会考虑芯片的RAM和ROM大小,因为这觉得了我们的很多功能,虽然可以采用外置的FLASH以及RAM芯片来扩展,但是无论使用了外置还是内置的空间,我们都需要去了解我们工程中使用了多少的RAM空间以及多少ROM空间。 今天我们就来分享一下

    2024年02月14日
    浏览(36)
  • 如何高效访问OneDrive个人存储空间?三种方法

    访问OneDrive有以下3种方式: 1.浏览器访问onedrive.live.com 电脑端和手机端都可以尝试一下,如果不行,可以切换不同的网络如移动流量、个人热点、WiFi等进行尝试,还不行的话则可能需要VPN服务 2.客户端访问 桌面端 下载地址:https://www.microsoft.com/zh-cn/microsoft-365/onedrive/download

    2024年02月05日
    浏览(43)
  • 高效的空间索引算法——Geohash 和 Google S2

     在空间索引类问题中,一个最普遍而又最重要的问题是:给定你某个点的坐标,你如何能够在海量的数据点中找到他所在的区域以及最靠近他的点?,比方说客户在路上突然想吃饭了,那么就要根据他的位置查询最近的餐馆并做出推荐。  通常情况下,一提到查找类问题,

    2024年01月20日
    浏览(35)
  • RabbitMQ工作队列模型详解:实现高效任务分配与消费

    深入探索RabbitMQ的work消息模型,学习如何在多个消费者之间有效分配任务。掌握能者多劳的策略,优化队列消费效率,提升系统性能。

    2024年02月11日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包