1.概念
队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,进行插入操作的一端称为队尾,插入操作为入队;进行删除操作的一端称为队头,删除操作为出队。队列的特点即先入先出。
首先了解下线性队列是如何实现的
即使用两个指针分别指向队头和队尾的位置,进行插入和删除操作时分别对队尾和队头的指针进行相应操作。但是这种做法会导致一些问题,如下图
随着部分元素的出队,队头部分位置空出来了,之后将不会被使用,造成了浪费,而当队列满了继续插入时还会出现数组越界的情况。由此产生了循环队列的方法,做法是,当两个指针任何时候到达尾部的位置时,循环跳到队头的位置,形成一个循环,如下图
这样避免了越界的问题,然而当rear和front相等时,无法判断当前状态是队空还是队满,为了达到判断队列状态的目的,可以通过牺牲一个存储空间来实现,如上图所示,队列的容量MAX_SIZE为4,当出现左下角的情况时,front = (rear+1)%MAX_SIZE,据此实现队列满的判断,牺牲了一个存储空间。
2.实现代码
xqQueue.cpp
//
// Created by 开机烫手 on 2018/3/17.
//
#ifndef QUEUE_XQQUEUE_H
#define QUEUE_XQQUEUE_H
#include <iostream>
using namespace std;
namespace xq {
const int MAX_QUEUE_SIZE = 50;
template<typename T>
class xqQueue {
private:
T *base;
int front;
int rear;
int size;
public:
xqQueue();
xqQueue(int);
bool insert(T);
bool delete_(T *);
bool isEmpty();
void print();
};
template<typename T>
xqQueue<T>::xqQueue() {
base = new T[MAX_QUEUE_SIZE];
front = rear = 0;
size = MAX_QUEUE_SIZE;
}
template<typename T>
xqQueue<T>::xqQueue(int n) {
base = new T[n];
front = rear = 0;
size = n;
}
template<typename T>
bool xqQueue<T>::isEmpty() {
if (rear == front)
return true;
return false;
}
template<typename T>
bool xqQueue<T>::insert(T num) {
if ((rear + 1) % size == front) {
cout << "queue is full!" << endl;
return false;
}
base[rear % size] = num;
rear = (rear + 1) % size;
}
template<typename T>
void xqQueue<T>::print() {
if (isEmpty()) {
cout << "queue is empty!" << endl;
return;
}
int p = front;
int q = rear;
while (p % size != q) {
cout << base[p] << ' ';
p = (p+1)%size;
}
cout << endl;
}
template<typename T>
bool xqQueue<T>::delete_(T *num) {
if (isEmpty()) {
cout << "queue is empty!" << endl;
return false;
}
*num = base[front];
front = (front + 1) % size;
}
}
#endif //QUEUE_XQQUEUE_H