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

《数据结构、算法与应用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指向的那一个位置)大1T* 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;elsetheBack--;
}
/*把元素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;elsetheFront = 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]);elseb.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.rhkb.cn/news/165219.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web前端面试-- 手写原生Javascript方法(new、Object.create)

web面试题 本人是一个web前端开发工程师&#xff0c;主要是vue框架&#xff0c;整理了一些面试题&#xff0c;今后也会一直更新&#xff0c;有好题目的同学欢迎评论区分享 ;-&#xff09; web面试题专栏&#xff1a;点击此处 手动实现Object.create 通过Object.create&#…

C/C++面试常见问题——指针和引用的区别

首先想要理解指针和引用的区别&#xff0c;我们要明确什么是指针&#xff0c;什么是引用 一&#xff0c;指针和引用的基本概念及特性 指针是一个特殊变量&#xff0c;其中存储着所指向变量的地址 指针主要有以下特性&#xff1a; 1. 在使用时需要*解引用 2. sizeof(指针)的…

STM32MP135和STM32MP157的区别

本文介绍了STMicroelectronics公司推出的两款多核处理器STM32MP135和STM32MP157之间的区别&#xff0c;包括主频、集成硬件模块数量、内存大小和电压调节模块等方面。 STMicroelectronics是一家领先的半导体解决方案提供商&#xff0c;在嵌入式系统领域有着丰富的经验。他们…

程序连接oracle查询数据的环境配置

连接oracle 数据库真麻烦&#xff0c;还是MySQL方便 Oracle Instant Client 这个东西的版本跟oracle的版本是有讲究的&#xff0c;引用文档的说明 Oracle 标准的客户端-服务器网络互操作性允许不同版本的 Oracle 客户端和 Oracle 数据库之间的连接。有关经过认证的配置&#…

JUC并发编程——各种锁的理解(基于狂神说的学习笔记)

各种锁的理解 公平锁与非公平锁 公平锁&#xff1a;非常公平&#xff0c;不能够插队&#xff0c;先来后到 非公平锁&#xff1a;可以插队&#xff0c;比较灵活&#xff08;默认都是非公平&#xff0c;如&#xff1a;synchronized,lock&#xff09; // Lock lock new Reent…

学习c#桌面应用编程 --- 我的第一个游戏

场景 我需要做一个c#桌面窗口软件&#xff0c;但是我曾经都是专职于java开发&#xff0c;但是java对windows并不是特别友好(awt除外)&#xff0c;于是必须需要掌握c#桌面编程&#xff0c;所以我需要手动做一个小游戏&#xff0c;来学习c#的一些基本桌面应用的知识。 开始 这…

Leetcode 剑指 Offer II 049. 求根节点到叶节点数字之和

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个二叉树的根节点 root &#xff0c;树中每个节点都存放有…

vue3后台管理系统之路由守卫

下载进度条 pnpm install nprogress //路由鉴权:鉴权,项目当中路由能不能被的权限的设置(某一个路由什么条件下可以访问、什么条件下不可以访问) import router from /router import setting from ./setting // eslint-disable-next-line typescript-eslint/ban-ts-comment /…

FreeRTOS入门教程(事件组概念和函数使用)

文章目录 前言一、事件组概念二、事件组和信号量&#xff0c;队列的区别三、事件组相关函数三、事件组应用示例1.等待多个事件2.任务同步 总结 前言 本篇文章将带大家学习什么是事件组以及如何使用事件组。 一、事件组概念 事件组通常是由一组位&#xff08;bits&#xff09…

Linux下的命令行参数和环境变量

命令行参数 什么是命令行参数 命令行参数是指在执行命令行程序时&#xff0c;给程序传递的额外参数。在Linux终端中&#xff0c;命令行参数通常通过在命令后面添加空格分隔的参数来传递。 Linux下以main函数举例说明 #include<stdio.h>int main(int argc char* argv[])…

Java:ApacheHttpClient连接寿命(timeToLive)未配置问题分析

一、问题描述 若 Apache HttpClient 未设置 timeToLive&#xff0c;通过服务域名访问服务的实例并且服务域名解析出的 IP 发生变化时&#xff0c;在短时间内会有部分请求出现连接异常错误。 二、问题分析 Apache HttpClient 通过服务域名从连接池获取连接&#xff0c;当连接…

[C语言]排序的大乱炖——喵喵的成长记

宝子&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重要…

睿趣科技:抖音小店新手运营攻略

随着短视频平台的兴起&#xff0c;抖音已经成为了一个炙手可热的营销工具。越来越多的商家选择在抖音上开设小店&#xff0c;以此来拓展自己的业务。那么&#xff0c;作为新手&#xff0c;如何运营好自己的抖音小店呢?本文将为您提供一些实用的建议。 首先&#xff0c;要明确自…

如何创建高效的 Python Docker 镜像详解

Docker是打包和部署容器中应用程序的行业标准软件。Docker镜像是构建和运行应用程序的基础&#xff0c;为了充分发挥Docker的潜力&#xff0c;您需要优化镜像以提高资源效率、安全性和性能。这将确保您的应用程序在Docker生态系统内无缝运行。 通过一个实际示例来学习如何实现…

Oracle监听服务启动后停止

问题 解决办法 找到listener.ora文件,箭头指的地方&#xff0c;host改为localhost 如何找到listener.ora 其中1522端口&#xff0c;是我新增的监听服务。之前这个host是一个固定的ip地址&#xff0c;我更换网络环境后&#xff0c;ip地址变了&#xff0c;所以导致监听启动失败。…

ChatGPT(1):ChatGPT初识

1 ChatGPT原理 ChatGPT 是基于 GPT-3.5 架构的一个大型语言模型&#xff0c;它的工作原理涵盖了深度学习和自然语言处理技术。以下是 ChatGPT 的工作原理的一些关键要点&#xff1a; 神经网络架构&#xff1a;ChatGPT 的核心是一个深度神经网络&#xff0c;采用了变种的 Tran…

vue-pdf多页预览异常,Rendering cancelled, page 1 Error at BaseExceptionClosure xxx

项目开发使用vue-pdf,单页情况预览正常&#xff0c;多页vue-pdf预览异常&#xff0c;第一次预览时&#xff0c;会先弹出异常模态窗口&#xff0c;关闭模态窗口&#xff0c;pdf又是正常显示&#xff0c;报错信息及异常截图如下&#xff1a; 报错信息 Rendering cancelled, page…

Nginx集群负载均衡配置完整流程

今天&#xff0c;良哥带你来做一个nginx集群的负载均衡配置的完整流程。 一、准备工作 本次搭建的操作系统环境是win11&#xff0c;linux可配置类同。 1&#xff09;首先&#xff0c;下载nginx。 下载地址为&#xff1a;http://nginx.org/en/download.html 良哥下载的是&am…

vulkan SDK安装

文章目录 一. vulcan官网二.安装流程 一. vulcan官网 https://vulkan.lunarg.com/sdk/home#windows 二.安装流程 点击下载 双击下载的*.exe进行安装 点击下一步 点击下一步 选择安装位置&#xff0c;点击下一步 点击全选&#xff0c;选择下一步 勾选同意&#xf…

2023年中国多功能折叠刀产量、销量及市场规模分析[图]

多功能折叠刀是一种集多种功能于一身的刀具&#xff0c;通常包括切割、开瓶、剥皮、锯木等功能&#xff0c;可以通过折叠和展开的方式来实现不同的功能&#xff0c;具有便携、多用途、安全等特点&#xff0c;广泛应用于户外探险、露营、自驾旅行等场景。 多功能折叠刀行业分类…