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

news2024/10/12 7:17:21

《数据结构、算法与应用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/1108959.html

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

相关文章

如何破解企业数字化转型的焦虑

在今年整体的大环境下&#xff0c;焦虑的不仅是个人&#xff0c;还有数字化转型中的企业。 01 焦虑中的企业数字化 焦虑往往不是来源于无知&#xff0c;而是未知&#xff01; 现阶段还未采取行动的企业会焦虑&#xff1a;现在开始是否会落后&#xff0c;市场红利是否会错过&…

JVS-rules中的基础与复合变量:规则引擎的心脏

JVS-rules中的“变量”概念与编程语言中的变量类似&#xff0c;但它们通常在规则系统中处理条件判断、业务结果复制场景&#xff0c;如下所示&#xff1a; 条件判断&#xff1a;在规则引擎中&#xff0c;规则通常由两个部分组成&#xff1a;条件和分支。变量用于描述条件部分中…

MongoDB实战之快速开始

写在前面&#xff1a;以前使用mongo只了解了个增删改查&#xff0c;而且没有集成springboot里面使用过。最近花了几小时系统的学习了一遍MongoDB,为了巩固和方便查找&#xff0c;在此记录下学习过程。 一、MongoDB的简介 MongoDB 是一个高性能、高可用性和易扩展的 NoSQL 数据…

idea设置字体大小快捷键 Ctrl+鼠标上下滑 字体快捷键缩放设置

双击 按住ctrl鼠标滑轮上划放大就好了 这个双击设置为&#xff0c;Ctrl鼠标下滑 字体缩小就好了

中文编程开发语言工具开发案例:多种称重方式编程实际例子

中文编程开发语言工具开发案例&#xff1a;多种称重方式编程实际例子 上图为 计价秤&#xff0c;使用串口通讯线连接电脑的主机&#xff0c;软件自动读取称的重量&#xff0c;自动计算金额。这种方式称重快速&#xff0c;不需再打印条码。 上图这个称重方式为 一体称称重&#…

CentOS7安装MySQL8.0.28

CentOS7安装MySQL8.0.28 一、下载MySQL安装包二、安装配置mysql 一、下载MySQL安装包 点击以下链接可以自动跳转&#xff1a;MySQL官网 接下来按如图所示依次点击进入。 选择自己所需要版本 此处如需下载历史版本可以点击 二、安装配置mysql 1、登录ssh或其他相关软件上…

电子奖牌-参数

产品参数 产品型号 ESL_6color_8.14_BLE 尺寸(mm) 200*135*7mm 显示技术 电子墨水屏 显示区域(mm) 180.22(H) * 101.38(V) 分辨率(像素) 1024*576 像素尺寸(mm) 0.176*0.176 144pdi 显示颜色 黑/白/红/黄/蓝/绿 外观颜色 实木色 视觉角度 180 工作温度 …

Yolov7代码解析

代码解析 backbone # -1代表前一层&#xff0c;channel:32 size:3 stride:1 [[-1, 1, Conv, [32, 3, 1]], # 0[-1, 1, Conv, [64, 3, 2]], # 1-P1/2 [-1, 1, Conv, [64, 3, 1]],[-1, 1, Conv, [128, 3, 2]], # 3-P2/4 #ELAN 4-11层[-1, 1, Conv, [64, 1, 1]],[-2, 1,…

蓝绿发布,灰度发布,滚动发布

写在前面 本文看下生产环境中有哪些常用的发布策略。 1:蓝绿发布 蓝绿发布要求将线上机器分成逻辑上的AB两&#xff08;蓝绿就是两种颜色&#xff09;组&#xff0c;升级时先将A组从负载均衡中摘除&#xff0c;由B组对外提供服务&#xff0c;如下图&#xff1a; 当A组升级…

代码随想录算法训练营第二十七天丨 回溯算法part04

93.复原IP地址 思路 其实只要意识到这是切割问题&#xff0c;切割问题就可以使用回溯搜索法把所有可能性搜出来&#xff0c;和刚做过的131.分割回文串 (opens new window)十分类似。 切割问题可以抽象为树型结构&#xff0c;如图&#xff1a; ​ 回溯三部曲 递归参数 在13…

浏览器中的网络钓鱼防护

网络钓鱼防护是一项功能&#xff0c;可保护用户免受旨在窃取其敏感信息的网络钓鱼攻击&#xff0c;网络钓鱼是网络犯罪分子常用的技术&#xff0c;这是一种社会工程攻击&#xff0c;诱使用户单击指向受感染网页的恶意链接&#xff0c;用户在该网页中感染了恶意软件或其敏感信息…

神经网络硬件加速器-DPU分析

一 DPU概述 DPU是专为卷积神经网络优化的可编程引擎&#xff0c;其使用专用指令集&#xff0c;支持诸多卷积神经网络的有效实现。 1、关键模块 卷积引擎&#xff1a;常规CONV等ALU&#xff1a;DepthwiseConvScheduler&#xff1a;指令调度分发Buffer Group&#xff1a;片上数据…

利用爬虫采集音频信息完整代码示例

以下是一个使用WWW::RobotRules和duoip.cn/get_proxy的Perl下载器程序&#xff1a; #!/usr/bin/perluse strict; use warnings; use WWW::RobotRules; use LWP::UserAgent; use HTTP::Request; use HTTP::Response;# 创建一个UserAgent对象 my $ua LWP::UserAgent->new();#…

鸿蒙状态栏设置

鸿蒙状态栏设置 基于鸿蒙 ArkTS API9&#xff0c;设置状态栏颜色&#xff0c;隐藏显示状态栏。 API参考文档 参考文档 新建项目打开之后发现状态栏是黑色的&#xff0c;页面颜色设置完了也不能影响状态栏颜色&#xff0c;如果是浅色背景&#xff0c;上边有个黑色的头&#…

C# LINQ常用操作方法——提升你的编程效率

导语&#xff1a;C# LINQ&#xff08;Language Integrated Query&#xff09;是一种强大且灵活的查询语言&#xff0c;可以将数据查询、过滤、排序和转换等操作无缝集成到C#代码中。本文将介绍一些常用的LINQ操作方法&#xff0c;帮助熟练掌握LINQ的使用&#xff0c;并进一步提…

【玩转 EdgeOne】边缘安全加速平台EO给自己的技术博客插上“翅膀”

目录 一、边缘安全加速平台 EO简介 二、产品功能 三、应用场景 四、网站加速体验 五、总结 作为一个技术博客爱好者&#xff0c;不知不觉已经在程序员行业将近十年了&#xff0c;写技术博客也有将近七年的时间&#xff0c;其中我也搭建了一个自己的技术博客&#xff0c;因…

iPhone 12电池寿命结果:四款机型都进行了比较

如果你想决定买哪款iPhone 12&#xff0c;电池寿命应该在你的清单上名列前茅。我们已经通过电池测试运行了所有新款iPhone 12&#xff0c;结果喜忧参半。 iPhone 12 mini是其中最小的一款&#xff0c;有一块小电池可供匹配&#xff0c;在5G上运行时间最短。iPhone 12和iPhone …

探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码

一、NIO简介 Java NIO&#xff08;New IO&#xff09;是Java SE 1.4引入的一个新的IO API&#xff0c;它提供了比传统IO更高效、更灵活的IO操作。与传统IO相比&#xff0c;Java NIO的优势在于它支持非阻塞IO和选择器&#xff08;Selector&#xff09;等特性&#xff0c;能够更…

基于下垂控制的孤岛双机并联逆变器环流抑制模型(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

分享一个Redis自带的压测工具:redis-benchmark

前言 今天给xdm分享一个Redis自带的压测工具&#xff1a;redis-benchmark。 介绍 redis-benchmark 是一个用于测试 Redis性能的基准测试工具&#xff0c;可以帮助开发人员评估和比较 Redis 在不同配置或负载情况下的吞吐量和延迟。 使用 redis-benchmark 可以执行多种类型的…