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

news2025/1/19 14:23:16

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

定义

队列的定义

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

队列的抽象数据类型

在这里插入图片描述

数组循环队列实现代码

_17queue.h

抽象类栈。

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

_18arrayQueue.h

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			数组存储的队列的头文件
*/
#pragma once
#ifndef _ARRAYQUEUE_H_
#define _ARRAYQUEUE_H_
#include<sstream>
#include<iostream>
#include "_1myExceptions.h"
#include "_17queue.h"
#include <cmath>
/*测试函数*/
void arrayQueueTest();

using namespace std;
template<class T>
class arrayQueue : public queue<T>
{
public:
    /*成员函数*/
    arrayQueue(int initialCapacity = 10);
    ~arrayQueue() { delete[] queue; }
    bool empty() const { return theFront == theBack; }
    int size() const //返回队列的元素个数
    {
        return (queueLength - theFront + theBack) % queueLength;
    }
    void clear() { theFront = theBack = 0; }/*清空队列中的元素*/
    int capacity() const { return queueLength-1; }
    //返回第一个元素
    T& front()
    {
        if (theFront == theBack)
            throw queueEmpty();
        return queue[(theFront + 1) % queueLength];
    }
    //返回最后一个元素
    T& back()
    {
        if (theFront == theBack)
            throw queueEmpty();
        return queue[theBack];
    }
    //删除队首元素
    void pop()
    {
        if (theFront == theBack)
            throw queueEmpty();
        theFront = (theFront + 1) % queueLength;
        queue[theFront].~T();
    }
    //向队尾插入元素theElement
    void push(const T& theElement);
    /*调整队列容量大小*/
    void resizeQueue(int newLength);
    void meld(arrayQueue<T>& a, arrayQueue<T>& b);//合并队列a,b到当前队列
    void split(arrayQueue<T>& a, arrayQueue<T>& b);//将当前队列分成两个队列a,b

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

    /*友元函数*/
    friend istream& operator>> <T>(istream& in, arrayQueue<T>& m);
    //输出但是不pop()元素
    friend ostream& operator<< <T>(ostream& out, arrayQueue<T>& m);
private:
    int theFront;       // 第一个元素的前一个位置
    int theBack;        // 最后一个元素的位置
    int queueLength;    // 队列的容量,实质上比队列容量(不包含queueFront指向的那一个位置)大1
    T* queue;           // 指向队列首地址的指针
};
/*友元函数*/
/*>>操作符*/
template<class T>
istream& operator>>(istream& in, arrayQueue<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(cinElement);
    }
    return in;
}
/*<<操作符*/
template<class T>
ostream& operator<<(ostream& out, arrayQueue<T>& m)
{
    int size = m.size();
    for (int i = 0; i < size; i++)
        out << m.queue[(m.theFront + i + 1) % m.queueLength] << "  ";
    out << endl;
    return out;
}
/*成员函数*/
/*构造函数*/
template<class T>
arrayQueue<T>::arrayQueue(int initialCapacity)
{
    if (initialCapacity < 1)
    {
        ostringstream s("");
        s << "Initial capacity = " << initialCapacity << "Must be > 0";
        throw illegalParameterValue(s.str());
    }
    queue = new T[initialCapacity+1];
    queueLength = initialCapacity+1;
    theFront = theBack = 0;
}

/*向队尾插入元素theElement*/
template<class T>
void arrayQueue<T>::push(const T& theElement)
{
    //首先检查队列是否已满,如已满,则将队列容量加倍
    if ((theBack + 1) % queueLength == theFront)
        resizeQueue(2 * (queueLength-1));    
    theBack = (theBack + 1) % queueLength;
    queue[theBack] = theElement;
}
/*调整队列容量大小*/
template<class T>
void arrayQueue<T>::resizeQueue(int newLength)
{
    T* temp = new T[newLength + 1];
    int size = min((*this).size(), newLength);
    for (int i = 0; i < size; i++)
        temp[i] = queue[(theFront + i + 1) % queueLength]; 
    queueLength = newLength+1;
    theFront = newLength;
    theBack = size - 1;
    delete[] queue;
    queue = temp;
}

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

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

_18arrayQueue.cpp

/*
Project name :			allAlgorithmsTest
Last modified Date:		2022年8月13日17点38分
Last Version:			V1.0
Descriptions:			测试_18arrayQueue.h头文件中的所有函数
*/
#include <iostream>
#include <time.h>
#include "_18arrayQueue.h"
using namespace std;

/*测试函数*/
void arrayQueueTest()
{
	cout << endl << "*********************************arrayQueueTest()函数开始*************************************" << endl;
	arrayQueue<int> a;

	//测试输入和输出
	cout << endl << "测试友元函数*******************************************" << endl;
	cout << "输入输出************************" << endl;
	cin >> a;
	cout << "arrayQueue 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()**************************" << endl;
	cout << "arrayQueue a is:" << a;
	a.push(99);
	a.push(22);
	cout << "arrayQueue a is:" << a;
	cout << "front()*************************" << endl;
	cout << "a.front() = " << a.front() << endl;
	cout << "back()**************************" << endl;
	cout << "a.back() = " << a.back() << endl;
	cout << "pop()***************************" << endl;
	cout << "before pop arrayQueue a is:" << a;
	a.pop();
	a.pop();
	cout << "after pop arrayQueue a is:" << a;
	cout << "resizeQueue()*******************" << endl;
	cout << "before resizeQueue a.capacity() = " << a.capacity()<<endl;
	a.resizeQueue(4);
	cout << "after resizeQueue a.capacity() = " << a.capacity() << endl;
	cout << "arrayQueue a is:" << a;
	cout << "a.front() = " << a.front() << endl;
	cout << "a.back() = " << a.back() << endl;
	a.push(88);
	cout << "after resizeQueue a.capacity() = " << a.capacity() << endl;
	cout << "meld()**************************" << endl;
	arrayQueue<int> b;
	cin >> b;
	cout << "arrayQueue a is:" << a;
	cout << "arrayQueue b is:" << b;
	arrayQueue<int> c;
	c.meld(a, b);
	cout << "arrayQueue c is:" << c;
	cout << "split()*************************" << endl;
	arrayQueue<int> d;
	arrayQueue<int> e;
	c.split(d, e);
	cout << "arrayQueue c is:" << c;
	cout << "arrayQueue d is:" << d;	
	cout << "arrayQueue e is:" << e;

	cout << endl << "测试成员函数性能***************************************" << endl;
	cout << "push()**************************" << endl;
	arrayQueue<int> f;
	double clocksPerMillis = double(CLOCKS_PER_SEC) / 1000;
	clock_t startTime = clock();
	for (int i = 0; i < 100000000; i++)
		f.push(i);
	double pushTime = (clock() - startTime) / clocksPerMillis;
	cout << 10000 << " push took " << pushTime << " ms" << endl;
	cout << "*********************************arrayQueueTest()函数结束*************************************" << endl;

}

main.cpp

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


int main()
{
	arrayQueueTest();
	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/1107261.html

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

相关文章

Matlab/C++源码实现RGB通道与HSV通道的转换(效果对比Halcon)

HSV通道的含义 HSV通道是指图像处理中的一种颜色模型&#xff0c;它由色调&#xff08;Hue&#xff09;、饱和度&#xff08;Saturation&#xff09;和明度&#xff08;Value&#xff09;三个通道组成。色调表示颜色的种类&#xff0c;饱和度表示颜色的纯度或鲜艳程度&#xf…

JAVA基础(JAVA SE)学习笔记(三)流程控制语句

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 JAVA基础&#xff08;JAVA SE&#xff09;学习笔记&#xff08;一&#xff09;JAVA学习路线、行业了解、…

Sql Server Report Service 使用简单说明

ReportServices做为报表服务器&#xff0c;结合sql直接访问数据库提供基本的报表格式设置显示&#xff0c;可以快速开发报表&#xff0c;主要包含两部分内容&#xff1a; 1.ReportServices服务器配置搭建&#xff0c;承载报表的运行平台 2.设计报表 ReportServices配置 1&am…

【C++初阶(二)】缺省参数函数重载

目录 前言 1. 缺省参数 1.1 什么是缺省参数 1.2 缺省参数的分类 1.2.1 全缺省参数 1.2.2 半缺省参数 2. 函数重载 2.1 什么是函数重载 2.2 缺省参数与函数重载 2.3 函数重载的使用 3. C支持函数重载的原因 总结 前言 在学习C语言时我们就会发现&#xff0c;C语言中存在的许多…

使用 Python 交互式方法预测股票价格变动概率

一、简介 当深入金融世界时,了解股价走势是一个显着的优势。在这里,我们提出了一种交互式方法,可以根据历史数据深入了解股价达到某些目标的可能性。 该工具利用 Python 强大的库,信息丰富且视觉上引人入胜。所提供的工具不会预测未来价格,而是评估价格波动的历史频率,让…

牛客网 -- WY28 跳石板

题目链接&#xff1a; 跳石板_牛客题霸_牛客网 (nowcoder.com) 解题步骤&#xff1a; 参考代码&#xff1a; void get_approximate(vector<int>& v,int n) {//求约数&#xff0c;从2到sqrt(n)即可&#xff0c;原因看图解//这里一定要等于sqrt(n)&#xff0c;例如16…

数据挖掘(6)聚类分析

一、什么是聚类分析 1.1概述 无指导的&#xff0c;数据集中类别未知类的特征&#xff1a; 类不是事先给定的&#xff0c;而是根据数据的相似性、距离划分的聚类的数目和结构都没有事先假定。挖掘有价值的客户: 找到客户的黄金客户ATM的安装位置 1.2区别 二、距离和相似系数 …

轻量级超分网络:Edge-oriented Convolution Block for Real-timeMM21_ECBSR 和 eSR

文章目录 ECBSR&#xff08;Edge-oriented Convolution Block for Real-timeMM21_ECBSR&#xff09;1. 作者目的是开发一个高效的适合移动端的超分网络。2. 作者决定使用plain net &#xff0c;但是效果不好&#xff0c;因此利用重参数化方法&#xff0c;丰富特征表示。3. re-p…

【数字人】6、ER-NeRF | 借助空间分解来实现基于 NeRF 的更高效的数字人生成(ICCV2023)

文章目录 一、背景二、方法2.1 问题设定2.2 Tri-Plane Hash Representation2.3 Region Attention Module2.4 训练细节 三、效果3.1 实验设定3.2 定量对比3.3 定性对比3.4 User study3.5 消融实验 四、代码4.1 视频数据预处理4.2 训练4.3 推理 论文&#xff1a;Efficient Region…

springboot+jaspersoft studio6制作报表

文章目录 前言一、开发工具下载安装二、开始制作1.新建1.文本2.图片3. 表格4.时间 三.遇到的问题1.中文不显示2.detail模块与column Footer之间有空白。怎么调节也消不掉 四.完整代码总结 前言 公司最近要做报销系统。需求就是将报销申请、报销审批。并将报销信息打印出来。 …

Nginx配置微服务避免actuator暴露

微服务一般在扫漏洞的情况下&#xff0c;需要屏蔽actuator健康检查 # 避免actuator暴露 if ($request_uri ~ "/actuator") { return 403; }

SD/SDIO(1):SD总线协议介绍

SD标准提供了很大的灵活性&#xff0c;除了作为存储卡外&#xff0c;还提供了SD卡槽的标准来扩展设备的功能。本篇文章就先来介绍一下SD总线的规范。对于SD/MMC协议的发展历史和概念介绍&#xff0c;可以参考我的这篇文章&#xff1a;SD、SDIO和MMC接口基础和规范介绍 文章目录…

【MySQL】数据库——库操作

文章目录 1. 创建数据库[IF NOT EXISTS] 的使用 2. 删除库3. 数据库的编码问题查看系统默认支持的字符集查看系统默认支持的校验集只查看 database的校验集指定编码创建数据库修改字符集修改校验集验证规则对数据库的影响utf8_general_ci ——不区分大小写utf8_bin ——区分大小…

【Qt之布局】QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout介绍及使用

在Qt中&#xff0c;布局管理器&#xff08;Layout&#xff09;用于管理窗口中的控件的位置和大小&#xff0c;以适应不同大小的窗口。 常用的布局管理器包括QVBoxLayout、QHBoxLayout、QGridLayout和QFormLayout。 先放张布局UI&#xff1a; 1. QVBoxLayout&#xff08;垂直布…

【爬虫教程】2023最详细的爬虫入门教程~

初识爬虫 学习爬虫之前&#xff0c;我们首先得了解什么是爬虫。 来自于百度百科的解释&#xff1a; 网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&a…

视频批量加水印:保护版权,提升效率

在当今的自媒体时代&#xff0c;视频制作已经成为许多人的一项必备技能。然而&#xff0c;在视频制作过程中&#xff0c;如何为自己的视频添加独特的水印以保护知识产权&#xff0c;常常让许多制作者感到困扰。本文将为你揭示如何通过固乔剪辑助手软件&#xff0c;简单几步批量…

音乐播放器蜂鸣器ROM存储歌曲verilog,代码/视频

名称&#xff1a;音乐播放器蜂鸣器ROM存储歌曲 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 设计音乐播放器&#xff0c;要求至少包含2首歌曲&#xff0c;使用按键切换歌曲&#xff0c;使用开发板的蜂鸣器播放音乐&#xff0c;使用Quartus内的RO…

VUE前端判断是电脑端还是移动端

背景需求 ruoyi框架&#xff0c;前后端分离。现在要在用户访问的时候根据不同的设备跳转到不同的登录页面。 教程 router/index.js 修改src/router/index.js&#xff0c;在这里增加自己的要跳转的页面 permission.js 在白名单中添加自己的登录页面 增加以下识别的代码 le…

solidworks 2024新功能之-打造更加智能的工作 硕迪科技

SOLIDWORKS 2024 的新增功能 SOLIDWORKS 的每个版本都致力于改进您的工作流程&#xff0c;使您常用的工具尽可能快速高效地运作。此外&#xff0c;SOLIDWORKS 2024 可以通过量身定制的解决方案扩展您的工具集&#xff0c;并使您能够通过 Cloud Services 轻松将您的设计数据连接…

vue 写一个大富翁 和 老虎机组件

大富翁 老虎机https://github.com/YaminZheng/zillionaire.git Vue Ts 编写的大富翁&#xff0c;支持自定义路径&#xff0c;动画和图片可以自行添加 Dev git clone https://github.com/YaminZheng/zillionaire.git cd zillionaire yarn set version stable yarn install …