学习了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; "):