队列(循环队列)

声明:图片及内容基于https://www.bilibili.com/video/av94331942

原理分析

数据结构

FIFO:先进先出

front指向头元素的前一个位置

rear指向最后一个元素

如果用rear=front来判断队列为空还是满,会出现歧义,其实无法判断

 

此时,若再插入一个元素,则rear=front。

为了解决这个问题,本问采取留出一个空间不用的策略。及队列容量始终比开辟空间少一。

基本数据类型

class CirQueue {
private:
    T* data;
    int front;
    int rear;
    int mSize;
public:
    CirQueue();
    CirQueue(int size);
    ~CirQueue();
    bool enQueue(T item);  //入队
    bool deQueue(T &item); //出队
    bool getFront(T& item);//获得队头
    bool isEmpty();
    bool isFull();
    void clearQueue();
    void displayQueue();
    int queueLength();     //获得队列长度
    class Out_of_range{};  //异常类
    class Empty{};         //异常类
}; 

队列初始化

template<class T>
CirQueue<T>::CirQueue()
{
    front = rear = 0;
    mSize = QUEUESIZE;
    data = new T[mSize];
}
template<class T>
CirQueue<T>::CirQueue(int size)
{
    mSize = size;
    front = rear = 0;
    data = new T[mSize];
}

析构函数

CirQueue<T>::~CirQueue()
{
    delete[] data;
}

入队(尾入)

而使用循环队列可以解决此问题,充分利用空间。

bool CirQueue<T>::enQueue(T item)
{
    if (isFull()) throw Out_of_range();
    rear = (rear + 1) % mSize;  //实现循环队列
    data[rear] = item;
    return true;
}

出队(头出)

template<class T>
bool CirQueue<T>::deQueue(T& item)
{
    if (isEmpty()) throw Empty();
    front = (front + 1) % mSize;
    item = data[front];
    return true;
}

获取头元素

template<class T>
bool CirQueue<T>::getFront(T& item)
{    
    if (isEmpty()) throw Empty();
    int i = (front + 1) % mSize;
    item = data[i];
    return true;
}

判断是否为空

rear = front时为空

template<class T>
bool CirQueue<T>::isEmpty()
{
    if (rear ==front) return true;
    return false;
}

判断是否为满

template<class T>
bool CirQueue<T>::isFull()
{
    if ((rear + 1) % mSize == front) return true;
    return false;
}

清空队列

void CirQueue<T>::clearQueue()
{
    front = rear = 0;
}

打印队列

template<class T>
void CirQueue<T>::displayQueue()
{    
    if (isEmpty()) {
        cout << "队列为空" << endl;
        return;
    }
    int i = (front + 1) % mSize;
    while (1) {                      //当front=head时表示下标到达最后一个元素,打印完这个元素以后再退出
        cout << data[i] << " ";
        if (i == rear) break;
        i = (i + 1) % mSize;
    }
    cout << endl;
}

获取队列长度

template<class T>
int CirQueue<T>::queueLength()
{
    int length = (rear + mSize - front) % mSize;
    return length;
}

完整代码

#include<iostream>
using namespace std;
const int QUEUESIZE = 100;
template <class T>
class CirQueue {
private:
    T* data;
    int front;
    int rear;
    int mSize;
public:
    CirQueue();
    CirQueue(int size);
    ~CirQueue();
    bool enQueue(T item);
    bool deQueue(T &item);
    bool getFront(T& item);
    bool isEmpty();
    bool isFull();
    void clearQueue();
    void displayQueue();
    int queueLength();
    class Out_of_range{};
    class Empty{};
};

template<class T>
CirQueue<T>::CirQueue()
{
    front = rear = 0;
    mSize = QUEUESIZE;
    data = new T[mSize];
}

template<class T>
CirQueue<T>::CirQueue(int size)
{
    mSize = size;
    front = rear = 0;
    data = new T[mSize];
}

template<class T>
CirQueue<T>::~CirQueue()
{
    delete[] data;
}

template<class T>
bool CirQueue<T>::enQueue(T item)
{
    if (isFull()) throw Out_of_range();
    rear = (rear + 1) % mSize;
    data[rear] = item;
    return true;
}

template<class T>
bool CirQueue<T>::deQueue(T& item)
{
    if (isEmpty()) throw Empty();
    front = (front + 1) % mSize;
    item = data[front];
    return true;
}

template<class T>
bool CirQueue<T>::getFront(T& item)
{    
    if (isEmpty()) throw Empty();
    int i = (front + 1) % mSize;
    item = data[i];
    return true;
}

template<class T>
bool CirQueue<T>::isEmpty()
{
    if (rear ==front) return true;
    return false;
}

template<class T>
bool CirQueue<T>::isFull()
{
    if ((rear + 1) % mSize == front) return true;
    return false;
}

template<class T>
void CirQueue<T>::clearQueue()
{
    front = rear = 0;
}

template<class T>
void CirQueue<T>::displayQueue()
{    
    if (isEmpty()) {
        cout << "队列为空" << endl;
        return;
    }
    int i = (front + 1) % mSize;
    while (1) {
        cout << data[i] << " ";
        if (i == rear) break;
        i = (i + 1) % mSize;
    }
    cout << endl;
}

template<class T>
int CirQueue<T>::queueLength()
{
    int length = (rear + mSize - front) % mSize;
    return length;
}
int main(){
    try {
        CirQueue<int> Queue(3);
        /*Queue.enQueue(1);
        Queue.enQueue(2);*/
        //int de  ;
        //Queue.deQueue(de);
        //cout << de << endl;
        //Queue.displayQueue();
        //if (Queue.isFull()) cout << "full";
        //cout << Queue.queueLength();
        //Queue.clearQueue();
        Queue.displayQueue();
    }
    catch (CirQueue<int>::Out_of_range) {
        cout << "已经满了" << endl;
    }
    catch (CirQueue<int>::Empty) {
        cout << "为空" << endl;
    }
    return 0;
}

 

posted @ 2021-03-12 18:36  gonghr  阅读(369)  评论(0编辑  收藏  举报