SeqQueue.h
#pragma once
#include<iostream>
#define MAXSIZE 20
using namespace std;
template<class DataType>
class SeqQueue
{
public:
SeqQueue(); //无参构造函数
SeqQueue(DataType arr[], int n); //带参构造函数,用一个数组初始化队列
~SeqQueue(); //析构函数
int GetLength(); //获得队列的长度
int GetRemainder(); //获得队尾还允许入队的空间
DataType GetHead(); //获取队首元素的值
DataType DelHead(); //队首元素出队,并返回出队元素
bool IsEmpty(); //判断队列为空
bool IsFull(); //判断队列是否为满
void EnQueue(DataType x); //入队,将元素x插入到队列中
void MoveAhead(); //当队首出队后,整个队列应当向前移动k位,否则一直插入队尾元素会导致假溢出
void Print(); //打印队列
void Clear(); //清空队列
private:
DataType *queue = new DataType[MAXSIZE]; //初始化时数组头为队首
int front; //队头指针
int rear; //队尾指针
int length; //队列长度
int remainder;//队尾还允许入队的空间
};
/*
队列是一种受限的线性表。它只允许在表的一端进行插入,另一端进行删除。
队列具有“先入先出”的特性,它的应用非常广泛,它主要应用在树的层次遍历、图的广度优先遍历、键盘的输入缓冲区、操作系统和事务管理等方面。
【定义】
队列(queue)是一种先进先出(First In First Out , FIFO)的线性表,它只允许在表的一端插入元素,另一端删除元素。
其中,允许插入的一端称为队尾(rear),允许删除的一端称为对头(front)。
*/
SeqQueue.cpp
#include"SeqQueue.h"
template<class DataType>
SeqQueue<DataType>::SeqQueue()
{
this->front = 0;
this->rear = 0;
this->length = 0;
this->remainder = MAXSIZE;
}
template<class DataType>
SeqQueue<DataType>::SeqQueue(DataType arr[], int n)
{
if (n > MAXSIZE) {
return;
}
this->front = 0; //队首元素的下标初始化为零
int i = 0;
for (; i < n; i++) {
this->queue[i] = arr[i];
}
this->rear = i - 1;//队尾元素的下标初始化为 i-1
this->length = n;
this->remainder = MAXSIZE - n;
}
template<class DataType>
SeqQueue<DataType>::~SeqQueue()
{
}
template<class DataType>
int SeqQueue<DataType>::GetLength()
{
return this->length;
}
template<class DataType>
int SeqQueue<DataType>::GetRemainder()
{//队尾还能允许入队的空间由两件事决定:this->front / 2 >= this->remainder 这个条件是否能成立:
//...若不成立,即使数组前端有空间也不能移动,此时允许入队的空间为 this->remainder;
//...若成立,此时允许入队的空间应为 this->remainder 再加上元素向前移动后留出的空间即 this->front.
if (this->front < 1) {
return this->remainder;
}
else if (this->front / 2 >= this->remainder) {
return this->remainder + this->front;
}
else{
return this->remainder;
}
}
template<class DataType>
DataType SeqQueue<DataType>::GetHead()
{
if (this->IsEmpty())
return -1;
return this->queue[this->front];
}
template<class DataType>
DataType SeqQueue<DataType>::DelHead()
{
if (this->IsEmpty())
return -1;
DataType temp = this->queue[this->front];
this->front++;
this->length--;
return temp;
}
template<class DataType>
bool SeqQueue<DataType>::IsEmpty()
{
if (this->length == 0)
return true;
else return false;
}
template<class DataType>
bool SeqQueue<DataType>::IsFull()
{
if (this->length == MAXSIZE)
return true;
else return false;
}
template<class DataType>
void SeqQueue<DataType>::EnQueue(DataType x)
{
if (this->IsFull())
return;
this->MoveAhead();
this->queue[this->rear + 1] = x;
this->rear++;
this->length++;
this->remainder--;
}
template<class DataType>
void SeqQueue<DataType>::MoveAhead()
{//当 this->remainder 充足时不使用此函数,因为移动元素将耗费时间为 o(this->length)
if (this->front < 1)
return;
int k = this->front;
if (k/2 >= this->remainder) { //当队首前的剩余空间/2 >= 队尾还允许入队的空间 时
for (int i = 0; i < this->length; i++) {
this->queue[i] = this->queue[i + k];
}
this->front = 0;
this->rear -= k;
this->remainder += k;
}
}
template<class DataType>
void SeqQueue<DataType>::Print()
{
if (this->IsEmpty())
return;
for (int i = this->front; i <= this->rear; i++) {
cout << this->queue[i] << " ";
if ((i-this->front+1) % 40 == 0)
cout << endl;
}
cout << endl;
}
template<class DataType>
void SeqQueue<DataType>::Clear()
{
this->front = 0;
this->rear = 0;
this->length = 0;
this->remainder = MAXSIZE;
}
SeqQueueTest.cpp
#include<iostream>
#include"SeqQueue.cpp"
using namespace std;
int main()
{
int arr[] = { 1,2,3,9,-4,15,-9,8,7,4,8,6,2,1,3,7,9,-11,10 };
int nA = sizeof(arr) / sizeof(arr[0]);
SeqQueue<int> TestA(arr, nA);
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 将元素33插入到队列中:" << endl;
TestA.EnQueue(33);
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 将元素34插入到队列中:" << endl;
TestA.EnQueue(34);
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 判断队列是否为满:" << TestA.IsFull() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 队首元素出队:" << TestA.DelHead() << endl;
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 将元素35插入到队列中:" << endl;
TestA.EnQueue(35);
cout << " 打印队列:";
TestA.Print();
cout << " 获得队列的长度:" << TestA.GetLength() << endl;
cout << " 队尾还允许入队的空间:" << TestA.GetRemainder() << endl;
cout << " 获取队首元素的值:" << TestA.GetHead() << endl;
cout << " 判断队列为空:" << TestA.IsEmpty() << endl;
cout << " 清空队列:" << endl;
TestA.Clear();
cout << " 判断队列为空:" << TestA.IsEmpty() << endl;
return 0;
}
