ArraySequentialQueue.h:
#pragma once
template<class T>
class Queue
{
public:
Queue(int queueCapacity = 10);
~Queue();
public:
//查看队列是否为空
bool IsEmpty() const;
//查看或者读取队首元素
T& Front() const;
//查看或者读取队尾元素
T& Rear() const;
//从队尾加入队列
void Push(const T& item);
//从队首删除书记
void Pop();
private:
T *queue;//用于申请一个动态数组
int front;//保存队首下标
int rear;//保存队尾下标
int capacity;//队列的容量
};
template<class T>
Queue<T>::Queue(int queueCapacity = 10) :capacity(queueCapacity)
{
//如果传入进来的队列大小小于1,则抛出异常
if (capacity < 1)
{
throw "Queue capacity must be >0";
}
queue = new T[capacity];
front = rear = 0;//刚开始队列中没有元素,
}
template<class T>
Queue<T>::~Queue()
{
delete[] queue;
}
//查看队列是否为空
template<class T>
inline bool Queue<T>::IsEmpty() const
{
return front == rear;
}
//查看或者读取队首元素
template<class T>
inline T& Queue<T>::Front() const
{
//判断队列是否为空
bool isEmpty = IsEmpty();
if (IsEmpty())
{
throw "Queue is empty. No front element";
}
//下面等价于return[(front + 1)%capacity],但总是遇到错误
int temp = front + 1;
int idx = temp % capacity;
return queue[idx]; //为什么+1?因为这个程序front指向的位置为空
}
//查看或者读取队尾元素
template<class T>
inline T& Queue<T>::Rear() const
{
//判断队列是否为空
if (IsEmpty())
{
throw "Queue is empty. No front element";
}
return queue[rear];
}
//从队尾加入队列
template<class T>
void Queue<T>::Push(const T& item)
{
判断rear是否指向队列最后一个单元
//if (rear == capacity - 1)
//{//如果是,则rear指向队列第一个单元,索引号为0
// rear = 0;
//}
//else
//{//如果不是,因为rear所指向的单元有数据,则rear++,然后插入新元素
// rear++;
//}
if ((rear + 1) % capacity == front) // 队列塞满元素了
{
//加倍
T* newQueue = new T[2 * capacity];
//首选判断有没有发生回绕
int start = (front + 1) % capacity;
if (start < 2)//没有回绕, no wrap//*********这个教程中这种判断是否回绕有问题
{//拷贝一次
copy(queue + start, queue + start + capacity-1, newQueue);
}
else
{
copy(queue + start, queue + capacity, newQueue);
copy(queue, queue + rear + 1, newQueue + capacity-start);
}
//重新调整
front = 2 * capacity - 1;//放在新队列最后
rear = capacity - 2;
capacity *= 2;
delete[] queue;
queue = newQueue;
}
//与上面的功能一样
rear = (rear + 1) % capacity;//高水平代码
queue[rear] = item;
}
//从队首删除书记
template<class T>
void Queue<T>::Pop()
{
//如果队列为空
if (IsEmpty())
{
throw "Queue is empty. Cannot delete.";
}
front = (front + 1) % capacity;
queue[front].~T();//可能队列元素为某个对象类型,删除之后需要调用其析构函数
}
Main.cpp:
#include <iostream>
#include "ArraySequentialQueue.h"
using namespace std;
int main()
{
Queue<char> q(5);
q.Push('A');
q.Push('B');
cout << q.Front()<<","<<q.Rear()<<" \n";
q.Push('C');
q.Push('D');
cout << q.Front() << "," << q.Rear() << " \n";
q.Push('E');
cout << q.Front() << "," << q.Rear() << " \n";
q.Push('F');
cout << q.Front() << "," << q.Rear() << " \n";
q.Push('G');
cout << q.Front() << "," << q.Rear() << " \n";
return 0;
}