环形队列的数组实现

本文介绍了基于数组实现的环形队列类模板,通过重载<<和>>运算符,实现了不同对象的实例化操作。具体代码展示了如何在Customer类中使用环形队列,并在main函数中通过不同数据类型(Customer和int)实例化环形队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习了imooc上James老师的视频,写了自己的环形队列的模板实现部分(基于数组),通过重载“<<输出运算符”和">>输入运算符",实现不同对象的实例化操作。具体代码如下:


类模板代码放于"MyQueueTemplate.h"头文件中:
#pragma once //(VS 2015,可换成"#ifndef...#define...#endif")

//环形队列类模板定义
template<typename T> //定义环形队列的数据类型为T
class MyQueue
{
public:
	MyQueue(int queueCapacity); //创建队列
	~MyQueue();                 //销毁队列
	void ClearQueue();          //清空队列
	bool QueueEmpty() const;    //判断队列是否为空
	bool QueueFull() const;     //判断队列是否为满
	int QueueLength() const;    //获取队列长度
	bool EnQueue(T &element);   //新元素入队,队尾
	bool DeQueue(T &element);   //首元素出队,队头
	void QueueTraverse();       //遍历队列

private:
	T *m_pQueue;            //队列数组指针
	int m_iQueueLen;        //队列元素个数
	int m_iQueueCapacity;   //队列数组容量
	int m_iHead;            //队头位置
	int m_iTail;            //队尾位置
};

//创建队列
template<typename T>
MyQueue<T>::MyQueue(int queueCapacity)
{
	m_iQueueCapacity = queueCapacity;	
	/*m_iHead = 0;
	m_iTail = 0;
	m_iQueueLen = 0;*/
	ClearQueue();
	m_pQueue = new T[m_iQueueCapacity];
	if (NULL == m_pQueue)
	{
		throw 1; //内存分配错误
	}
}

//销毁队列
template<typename T>
MyQueue<T>::~MyQueue()
{
	delete[]m_pQueue;
	m_pQueue = NULL;
}

//清空队列
template<typename T>
void MyQueue<T>::ClearQueue()
{
	m_iHead = 0;
	m_iTail = 0;
	m_iQueueLen = 0;
}

//判断当前队列是否为空
template<typename T>
bool MyQueue<T>::QueueEmpty() const
{
	/*if (0 == m_iQueueLen)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return (0 == m_iQueueLen) ? true : false;
}

//判断当前队列是否为满
template<typename T>
bool MyQueue<T>::QueueFull() const
{
	return (m_iQueueCapacity == m_iQueueLen) ? true : false;
}

//获取队列元素个数
template<typename T>
int MyQueue<T>::QueueLength() const
{
	return m_iQueueLen;
}

//新元素入队,队尾
template<typename T>
bool MyQueue<T>::EnQueue(T &element)
{
	if (QueueFull())
	{
		throw 2; //队列已满,插入失败
	}
	else
	{
		m_pQueue[m_iTail] = element; //拷贝构造函数
		m_iTail++;
		m_iTail %= m_iQueueCapacity;
		m_iQueueLen++; //队列元素个数加1(不要漏了)
		return true;
	}
}

//首元素出队,队头
template<typename T>
bool MyQueue<T>::DeQueue(T &element)
{
	if (QueueEmpty())
	{
		throw 3; //队列为空,删除失败
	}
	else
	{
		element = m_pQueue[m_iHead]; //拷贝构造函数
		m_iHead++;
		m_iHead %= m_iQueueCapacity;
		m_iQueueLen--; //队列元素个数减1(不要漏了)
		return true;
	}
}

//遍历队列
template<typename T>
void MyQueue<T>::QueueTraverse()
{
	if (QueueEmpty())
	{
		cout << "队列为空,遍历结束" << endl;
	}
	else
	{
		cout << "队列元素为:" << endl;
		for (int i = m_iHead; i < m_iHead + m_iQueueLen; i++)
		{
			cout << m_pQueue[i % m_iQueueCapacity] << endl; //针对具体的队列对象进行访问
		}
		cout << endl;
	}
}

上面即为环形队列的类模板,此处模板参数列表仅包含一个数据类型,可以根据需要加以改变。。。

接着定义一个Customer的类,包含string类型的name,和int类型的age,用于展示环形队列类模板的正确性。"Customer.h"和"Customer.cpp"文件如下:

"Customer.h"文件:
#pragma once

#include "string"
using namespace std;

class Customer
{
	friend ostream & operator<<(ostream &out, const Customer &customer); //<<运算符重载,友元函数实现
	friend istream & operator>>(istream &in, Customer &customer); //>>运算符重载,友元函数实现
public:
	Customer(string name = "", int age = 0);
private:
	string m_strName;
	int m_iAge;
};


"Customer.cpp"文件:
#include "Customer.h"
#include <iomanip>

Customer::Customer(string name /* = "Jim" */, int age /* = 20 */)
{
	m_strName = name;
	m_iAge = age;
}

//<<输出运算符重载
ostream & operator<<(ostream &out, const Customer &customer)
{
	out << setiosflags(ios::left) << "姓名:" << setw(15) << customer.m_strName
		<< "\t" << "年龄:" << setw(5) << customer.m_iAge; //左对齐
	return out;
}

//>>输入运算符重载
istream & operator>>(istream &in, Customer &customer)
{	
	in >> customer.m_strName >> customer.m_iAge;
	return in;
}

以上为Customer类的定义及实现。。。在main()函数中,通过不同的数据类型来实例化不同的模板队列,代码如下:

main()函数:
#include <iostream>
#include "MyQueueTemplate.h"
#include "Customer.h"
using namespace std;

/************************************************************************/
/* 实现环形队列                                                         */
/************************************************************************/

typedef Customer ElemType; //根据需要定义数据类型,此时为Customer类型的环形队列
//typedef int ElemType; //int类型的环形队列

void printChoose();

int main(void)
{
	try
	{
		MyQueue<ElemType> queue(4); //环形队列大小,此处为4		
		ElemType value;
		int choice = 0;
		printChoose();
		do 
		{
			cout << "选择:";
			cin >> choice;
			switch (choice)
			{
			case 1:
				cout << "输入元素:";
				cin >> value; //通过">>"运算符重载,实现不同数据类型的输入
				queue.EnQueue(value);
				break;
			case 2:
				queue.DeQueue(value);				
				cout << "删除的元素是:";
				cout << value << endl; //通过"<<"运算符重载,实现不同数据类型的输入
				break;
			case 3:
				queue.QueueTraverse();
				break;
			case 4:
				queue.ClearQueue();
				break;
			case 5:
				printChoose();
				break;
			default:
				break;
			}
		} while (choice);
	}
	catch (int &exception)
	{
		if (1 == exception)
		{
			cout << "内存分配失败" << endl;
		}
		if (2 == exception)
		{
			cout << "队列已满,插入失败" << endl;
		}
		if (3 == exception)
		{
			cout << "队列为空,删除失败" << endl;
		}
	}
	catch (...)
	{
		cout << "未知错误,程序终止" << endl;
	}

	return 0;
}

void printChoose()
{
	cout << "******************************" << endl;
	cout << "********* 1 插入元素 *********" << endl;
	cout << "********* 2 删除元素 *********" << endl;
	cout << "********* 3 遍历队列 *********" << endl;
	cout << "********* 4 清除队列 *********" << endl;
	cout << "********* 5 显示菜单 *********" << endl;
	cout << "********* 0 退出程序 *********" << endl;
}

图一为Customer类型的环形队列("typedef Customer ElemType; "):



图2为int类型的环形队列("typedef int ElemType; "):


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值