《数据结构、算法与应用C++语言描述》使用C++语言实现数组双端队列

news2024/12/25 9:30:44

《数据结构、算法与应用C++语言描述》使用C++语言实现数组双端队列

定义

队列的定义

队列(queue)是一个线性表,其插入和删除操作分别在表的不同端进行。插入元素的那一端称为队尾(back或rear),删除元素的那一端称为队首(front)。

队列的抽象数据类型

在这里插入图片描述

链表队列代码

数组双端队列实现

_19deque.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			无序的双端队列的抽象类的头文件
*/
#pragma once
#ifndef _DEQUE_H_
#define _DEQUE_H_
template<class T>
class deque
{
public:
	virtual ~deque() {}
	virtual bool empty() const = 0;//返回true,当且仅当队列为空
	virtual int size() const = 0;//返回队列中元素个数
	virtual T& front() = 0;//返回头元素的引用
	virtual T& back() = 0;//返回尾元素的引用
	virtual void pop_front() = 0;//删除首元素
	virtual void pop_back() = 0;//删除尾元素
	virtual void push_front(const T& theElement) = 0;//把元素theELment加入队首
	virtual void push_back(const T& theElement) = 0;//把元素theELment加入队尾
};
#endif

_20arrayDeque.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			数组存储的无序的双端队列类的头文件
*/
#pragma once
#ifndef _ARRAYDEQUE_H_
#define _ARRAYDEQUE_H_
#include<sstream>
#include<iostream>
#include "_1myExceptions.h"
#include "_19deque.h"
/*测试函数*/
void arrayDequeTest();
template<class T>
class arrayDeque : public deque<T>
{
public:
	/*成员函数*/
	/*构造函数*/
	arrayDeque(int initialCapacity = 10);
	/*析构函数*/
	~arrayDeque() {
		delete[]  deque;
	}
	bool empty() const { return theFront == theBack; };//返回true,当且仅当队列为空
	int size() const { return (dequeLength - theFront + theBack)%dequeLength; };//返回队列中元素个数
	int capacity() const {
		return dequeLength - 1;
	}
	void clear() { theFront = theBack = 0; }
	T& front();//返回头元素的引用
	T& back();//返回尾元素的引用
	void pop_front();//删除首元素
	void pop_back();//删除尾元素
	void push_front(const T& theElement);//把元素theELment加入队首
	void push_back(const T& theElement);//把元素theELment加入队尾
	/*调整队列容量大小*/
	void resizeDeque(int newLength);
	void meld(arrayDeque<T>& a, arrayDeque<T>& b);
	void split(arrayDeque<T>& a, arrayDeque<T>& b);

	/*重载操作符*/
	/*重载[]操作符*/
	T operator[](int i) { return deque[(theFront + i + 1) % dequeLength]; }

	/*友元函数*/
	friend istream& operator>> <T>(istream& in, arrayDeque<T>& m);
	//输出但是不pop()元素
	friend ostream& operator<< <T>(ostream& out, arrayDeque<T>& m);
private:
	int theFront;       // 第一个元素的前一个位置
	int theBack;        // 最后一个元素的位置
	int dequeLength;    // 队列的容量,实质上比队列容量(不包含queueFront指向的那一个位置)大1
	T* deque;
};

/*友元函数*/
/*>>操作符*/
template<class T>
istream& operator>>(istream& in, arrayDeque<T>& m)
{
	int numberOfElement = 0;
	cout << "Please enter the number of element:";
	while (!(in >> numberOfElement))
	{
		in.clear();//清空标志位
		while (in.get() != '\n')//删除无效的输入
			continue;
		cout << "Please enter the number of element:";
	}
	T cinElement;
	for (int i = 0; i < numberOfElement; i++)
	{
		cout << "Please enter the element " << i + 1 << ":";
		while (!(in >> cinElement))
		{
			in.clear();//清空标志位
			while (in.get() != '\n')//删除无效的输入
				continue;
			cout << "Please enter the element " << i + 1 << ":";
		}
		m.push_back(cinElement);
	}
	return in;
}
/*<<操作符*/
template<class T>
ostream& operator<<(ostream& out, arrayDeque<T>& m)
{
	int size = m.size();
	for (int i = 0; i < size; i++)
		out << m.deque[(m.theFront + i + 1) % m.dequeLength] << "  ";
	out << endl;
	return out;
}

/*构造函数*/
template<class T>
arrayDeque<T>::arrayDeque(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		ostringstream s("");
		s << "Initial capacity = " << initialCapacity << "Must be > 0";
		throw illegalParameterValue(s.str());
	}
	deque = new T[initialCapacity + 1];
	dequeLength = initialCapacity + 1;
	theFront = theBack = 0;
}
/*返回头元素的引用*/
template<class T>
T& arrayDeque<T>::front()
{
	if(theFront == theBack)
		throw queueEmpty();
	return deque[(theFront + 1) % dequeLength];
}
/*返回尾元素的引用*/
template<class T>
T& arrayDeque<T>::back()
{
	if (theFront == theBack)
		throw queueEmpty();
	return deque[theBack];
}
/*删除首元素*/
template<class T>
void arrayDeque<T>::pop_front()
{
	/*检查是否为空,为空就抛出异常*/
	if (theFront == theBack)
		throw queueEmpty();
	/*不为空就删除首元素*/
	theFront = (theFront + 1) % dequeLength;
	deque[theFront].~T();
}
/*删除尾元素*/
template<class T>
void arrayDeque<T>::pop_back()
{
	/*检查是否为空,为空就抛出异常*/
	if (theFront == theBack)
		throw queueEmpty();
	/*不为空就删除尾元素*/
	deque[theBack].~T();
	if (theBack == 0)
		theBack = dequeLength - 1;
	else
		theBack--;
}
/*把元素theELment加入队首*/
template<class T>
void arrayDeque<T>::push_front(const T& theElement)
{
	/*判断队列是否满了,如果满了,就调整容量为原来的两倍*/
	if ((theFront + 1) % dequeLength == theBack)
		resizeDeque(2 * (dequeLength-1));
	deque[theFront] = theElement;
	if (theFront == 0)
		theFront = dequeLength - 1;
	else
		theFront = theFront - 1;
}
/*把元素theELment加入队尾*/
template<class T>
void arrayDeque<T>::push_back(const T& theElement)
{
	/*判断队列是否满了,如果满了,就调整容量为原来的两倍*/
	if ((theBack + 1) % dequeLength == theFront)
		resizeDeque(2 * (dequeLength - 1));
	theBack = (theBack + 1) % dequeLength;
	deque[theBack] = theElement;
}

/*调整队列容量大小*/
template<class T>
void arrayDeque<T>::resizeDeque(int newLength)
{
	T* temp = new T[newLength + 1];
	int size = min((*this).size(), newLength);
	for (int i = 0; i < size; i++)
		temp[i] = deque[(theFront + i + 1) % dequeLength];
	dequeLength = newLength + 1;
	theFront = newLength;
	theBack = size - 1;
	delete[] deque;
	deque = temp;
}

/*
创建一个新的队列,该表包含了a和b中的所有元素,其中a和b的元素轮流出现,表中的首
元素为a中的第一个元素。在轮流排列元素时,如果某个队列的元素用完了,则把另一个队列的其
余元素依次添加在新队列的后部。代码的复杂性应与两个输入队列的长度呈线性比例关系。
归并后的线性队列是调用对象*this
*/
template <class T>
void arrayDeque<T>::meld(arrayDeque<T>& a, arrayDeque<T>& b)
{
	(*this).clear();
	int i = 0;
	while (i < a.size() && i < b.size())
	{
		push_back(a[i]);
		push_back(b[i]);
		i++;
	}
	while (i < a.size())
	{
		push_back(a[i]);
		i++;
	}
	while (i < b.size())
	{
		push_back(b[i]);
		i++;
	}
}

/*生成两个线性队列a和b,a包含*this中索引为奇数的元素,b包含其余的元素*/
template<class T>
void arrayDeque<T>::split(arrayDeque<T>& a, arrayDeque<T>& b)
{
	a.clear();
	b.clear();
	int size = (*this).size();
	for (int i = 0; i < size; i++)
	{
		if (i % 2 == 0)
			a.push_back(deque[(theFront + i + 1) % dequeLength]);
		else
			b.push_back(deque[(theFront + i + 1) % dequeLength]);
	}
}

#endif

_20arrayDeque.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			测试_20arrayDeque.h头文件中的所有函数
*/
#include <iostream>
#include "_20arrayDeque.h"
using namespace std;
/*测试函数*/
void arrayDequeTest()
{
	cout << endl << "*********************************arrayDequeTest()函数开始*************************************" << endl;
	arrayDeque<int> a;
	//测试输入和输出
	cout << endl << "测试友元函数*******************************************" << endl;
	cout << "输入输出************************" << endl;
	cin >> a;
	cout << "arrayDeque a is:" << a;
	cout << endl << "测试成员函数*******************************************" << endl;
	cout << "empty()*************************" << endl;
	cout << "a.empty() = " << a.empty() << endl;
	cout << "size()**************************" << endl;
	cout << "a.size() = " << a.size() << endl;
	cout << "capacity()**********************" << endl;
	cout << "a.capacity() = " << a.capacity() << endl;
	cout << "push_front()********************" << endl;
	cout << "before push_front() arrayDeque a is:" << a;
	a.push_front(99);
	a.push_front(22);
	cout << "after push_front() arrayDeque a is:" << a;
	cout << "push_back()*********************" << endl;
	cout << "before push_back() arrayDeque a is:" << a;
	a.push_back(99);
	a.push_back(22);
	cout << "after push_back() arrayDeque a is:" << a;
	cout << "front()*************************" << endl;
	cout << "a.front() = " << a.front() << endl;
	cout << "back()**************************" << endl;
	cout << "a.back() = " << a.back() << endl;
	cout << "pop_front()*********************" << endl;
	cout << "before pop_front arrayDeque a is:" << a;
	a.pop_front();
	a.pop_front();
	cout << "after pop_front arrayDeque a is:" << a;
	cout << "pop_back()**********************" << endl;
	cout << "before pop_back arrayDeque a is:" << a;
	a.pop_back();
	a.pop_back();
	cout << "after pop_back arrayDeque a is:" << a;
	cout << "resizeDeque()*******************" << endl;
	cout << "before resizeDeque a.capacity() = " << a.capacity() << endl;
	a.resizeDeque(4);
	cout << "after resizeDeque a.capacity() = " << a.capacity() << endl;
	cout << "resizeDeque a is:" << a;
	cout << "a.front() = " << a.front() << endl;
	cout << "a.back() = " << a.back() << endl;
	a.push_back(88);
	cout << "after resizeDeque a.capacity() = " << a.capacity() << endl;
	cout << "meld()**************************" << endl;
	arrayDeque<int> b;
	cin >> b;
	cout << "arrayDeque a is:" << a;
	cout << "arrayDeque b is:" << b;
	arrayDeque<int> c;
	c.meld(a, b);
	cout << "arrayDeque c is:" << c;
	cout << "split()*************************" << endl;
	arrayDeque<int> d;
	arrayDeque<int> e;
	c.split(d, e);
	cout << "arrayDeque c is:" << c;
	cout << "arrayDeque d is:" << d;
	cout << "arrayDeque e is:" << e;
	cout << "*********************************arrayDequeTest()函数结束*************************************" << endl;

}

_1main.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			main()函数,控制运行所有的测试函数
*/
#include <iostream>
#include "_20arrayDeque.h"

int main()
{
	arrayDequeTest();
	return 0;
}

_1myExceptions.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			综合各种异常
*/
#pragma once
#ifndef _MYEXCEPTIONS_H_
#define _MYEXCEPTIONS_H_
#include <string>
#include<iostream>

using namespace std;

// illegal parameter value
class illegalParameterValue 
{
   public:
      illegalParameterValue(string theMessage = "Illegal parameter value")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal input data
class illegalInputData 
{
   public:
      illegalInputData(string theMessage = "Illegal data input")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal index
class illegalIndex 
{
   public:
      illegalIndex(string theMessage = "Illegal index")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix index out of bounds
class matrixIndexOutOfBounds 
{
   public:
      matrixIndexOutOfBounds
            (string theMessage = "Matrix index out of bounds")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix size mismatch
class matrixSizeMismatch 
{
   public:
      matrixSizeMismatch(string theMessage = 
                   "The size of the two matrics doesn't match")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// stack is empty
class stackEmpty
{
   public:
      stackEmpty(string theMessage = 
                   "Invalid operation on empty stack")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// queue is empty
class queueEmpty
{
   public:
      queueEmpty(string theMessage = 
                   "Invalid operation on empty queue")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// hash table is full
class hashTableFull
{
   public:
      hashTableFull(string theMessage = 
                   "The hash table is full")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// edge weight undefined
class undefinedEdgeWeight
{
   public:
      undefinedEdgeWeight(string theMessage = 
                   "No edge weights defined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// method undefined
class undefinedMethod
{
   public:
      undefinedMethod(string theMessage = 
                   "This method is undefined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};
#endif

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

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

相关文章

网站二级域名怎么部署SSL证书?

二级域名是在主域名下创建的子域名&#xff0c;常用于区分不同功能或部门的网站。随着互联网的发展&#xff0c;越来越多的网站开始采用二级域名来构建更灵活和个性化的网站结构&#xff0c;保护二级域名的数据安全也变得至关重要。为了确保二级域名的安全性&#xff0c;申请SS…

python爬虫requests.get乱码问题

爬取百度图片的时候res.text出现乱码&#xff1a; 解决&#xff1a; 删除请求头中的接受编码项

当量因子法、InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估中的应用及论文写作、拓展分析

生态系统服务是人类从自然界中获得的直接或间接惠益&#xff0c;可分为供给服务、文化服务、调节服务和支持服务4类&#xff0c;对提升人类福祉具有重大意义&#xff0c;且被视为连接社会与生态系统的桥梁。自从启动千年生态系统评估项目&#xff08;Millennium Ecosystem Asse…

excel表格怎么设置数据超链接?

在Excel表格中&#xff0c;可以设置超链接来快速导航到其他单元格、工作表、文件、网页等。下面我将详细介绍如何设置数据超链接。 1. 在Excel表格中选择要添加超链接的单元格或文本。 2. 使用鼠标右键点击选定的单元格&#xff0c;然后选择“超链接”选项&#xff0c;或者在…

2023下半年信息系统集成设计师案例

案例题 重要的知识点容易忽略的知识点不错的小题合同管理配置管理变更管理成本管理招标管理人力资源管理质量管理风险管理沟通管理立项和需求 能说专业术语&#xff08;比喻十大领域管理不足&#xff09;就说&#xff0c;没法说的大白话也没问题 重要的知识点 如果题目没有说从…

Bazzite:专为 Steam Deck 和 PC 上的 Linux 游戏打造的发行版

导读对于一个专为 Linux 游戏定制的发行版&#xff0c;你是否感兴趣呢&#xff1f;如果答案是肯定的&#xff0c;那么我们为你准备了绝佳选择。 Bazzite 是一个新推出的基于 Fedora 的发行版&#xff0c;它是为 Linux 桌面上的游戏&#xff0c;以及越来越火热的 Steam Deck 定…

必不可少的UI组件二——组件库开发的基础知识(工程化篇)

组件库工程化概述 在 必不可少的UI组件——组件库开发的基础知识(Vue篇) 中&#xff0c;我们介绍了一些封装 Vue 组件的过程中高频使用到的框架技巧&#xff0c;但是&#xff0c;这并不足以支持我们实现完善的组件库。 建设一个成熟的组件库就像盖一幢大楼&#xff0c;工程化…

开发从0 到1获取代码,提交,推送

1,首先我们要下载git 2,下载一个github desktop 3,下载好git 后拉取代码 git clone 克隆的地址 4&#xff0c;克隆好项目后&#xff0c;配置git 密钥到你的账号上 4.1没有有密钥怎么生成&#xff1f; git config --global user.name "xxx" git config --globa…

无线射频收发芯片:Si24R2F

Si24R2F是一款2.4GHz超低功耗有源RFID标签系统的SoC单芯片&#xff0c;集成嵌入式2.4GHz无线射频发射器模块、64次可编程NVM存储器模块以及自动发射控Z器模块等。 Si24R2F支持4通道轮询发射&#xff0c;4个信道可以轮流发射不同的数据&#xff0c;从而增加系统卡片容量。同时支…

温湿度实时监测,这个方法太强了!

温湿度监控是现代社会中一个日益重要的技术领域&#xff0c;它不仅涉及到人们的日常生活&#xff0c;也在各种产业和领域中发挥着至关重要的作用。随着科技的不断进步&#xff0c;我们对环境条件的监测和控制需求愈发增强。 客户案例 制药行业 在制药行业&#xff0c;药品的质量…

Si24R2H无线射频芯片 125KHz唤醒功能

​ 产品信息: Si24R2H-2.4GHz无线发射单芯片 集成嵌入式基带 发射频率范围&#xff1a;2400MHz~2525MHz 接收频率范围&#xff1a;15KHz~150KHz 支持2Mbps、1Mbps和250Kbps三种发射数据速率 产品功能: 1、高精度的位置定位 2、测温和报J 3、实现与手机的联动 4、外W设…

后台管理系统SQL注入漏洞

对于edu来说&#xff0c;是新人挖洞较好的平台&#xff0c;本次记录一次走运的捡漏0x01 前景 在进行fofa盲打站点的时候&#xff0c;来到了一个后台管理处看到集市二字&#xff0c;应该是edu站点 确认目标身份&#xff08;使用的quake进行然后去ipc备案查询&#xff09; 网…

wps表格求标准差怎么算?

在WPS表格中&#xff0c;要计算标准差&#xff0c;可以使用STDEV函数。标准差是一种衡量数据集合离散程度的统计指标。下面我将详细介绍如何使用STDEV函数来计算标准差。 STDEV函数的语法为&#xff1a;STDEV(range) 其中&#xff0c;range表示要计算标准差的数据范围&#x…

视频怎么压缩?视频过大这样压缩变小

在日常生活中&#xff0c;我们常常会遇到需要压缩视频的情况&#xff0c;视频压缩不仅可以减小文件大小&#xff0c;方便存储和传输&#xff0c;还可以在保证质量的同时&#xff0c;满足不同的使用需求。那么&#xff0c;如何有效地压缩视频呢&#xff1f; 方法一&#xff1a;嗨…

云函数cron-parser解析时区问题

1、问题 云函数部署后cron-parser解析0点会变成8点 考虑可能是时区的问题 然后看文档发现果然有问题&#xff0c;云函数环境是utc0 2、解决 看了半天cron-parser文档发现 Using Date as an input can be problematic specially when using the tz option. The issue bein…

爬虫学习日记第八篇(爬取fofa某端口的协议排行及其机器数目,统计top200协议)

需求 找到最常用的200个协议 通过fofa搜索端口&#xff0c;得到协议排名前五名和对应机器的数目。 遍历端口&#xff0c;统计各个协议对应的机器数目&#xff08;不准&#xff0c;但能看出个大概&#xff09; 读写API API需要会员&#xff0c;一天只能访问1000次。 import…

用护眼灯到底好不好?好用热门的护眼台灯推荐

现在市面上做护眼灯的品牌非常多&#xff0c;有的是脚踏实地&#xff0c;真正做保护消费者眼睛的产品&#xff0c;有的则是夸大宣传&#xff0c;以次充好来收割很多不明真相的群众。其实护眼灯的防蓝光是做不到完全无蓝光的&#xff0c;那些宣传完全无蓝光的商家&#xff0c;完…

doc与docx文档转html,格式样式不变(包含图片转换)

最近做一个富文本的需求&#xff0c;要求把文档内容转换到富文本内&#xff0c;文档中的格式也好&#xff0c;样式也好&#xff0c;图片啥的都要一致展示&#xff1b;踩了不少坑&#xff0c;据说word文档其实是一个压缩包&#xff0c;我不是特别清楚但是也能理解&#xff0c;自…

爬虫用什么库更事半功倍?

1、首先&#xff0c;我们需要安装 TypeScript 和 superagent 库。在命令行中运行以下命令来安装它们&#xff1a; npm install typescript npm install superagent2、创建一个新的 TypeScript 项目&#xff0c;并在项目中创建一个名为 crawler 的文件夹。在 crawler 文件夹中&a…

Qt判断一个点在多边形内还是外(支持凸边形和凹变形)

这里实现的方法是转载于https://blog.csdn.net/trj14/article/details/43190653和https://blog.csdn.net/WilliamSun0122/article/details/77994526 来实现的&#xff0c;并且按照Qt的规则进行了调整。 以下实现方法有四种&#xff0c;每种方法的具体讲解在转载的博客中有说明&…