基于数组的循环队列C++实现

1. 思想

在这里插入图片描述

如果不采用循环的方法,那么这种情况下左边一大半空间都无法利用效率低下。为此,考虑循环的思想,即考虑循环的方法,将其视作一个“环”。

假设建立的数组的大小为s i z e sizesize,那么环的周期就是s i z e sizesize,索引为i ii的元素其前一元素为( i + 1 ) % s i z e (i+1)\%size(i+1)%size,后一元素为( i − 1 ) % s i z e (i-1)\%size(i1)%size。这样就可以将环视作一个正常的数组队列,只是前后元素的表示发生了改变而已。

重点:如何判定队列已满或者队列为空?

如果不预留一个空位的话,是无法判定队列为空或者队列已满的,例如下面这种情况就无法判定到底是空的还是满的。

在这里插入图片描述

为了能够分别这两种情况就必须在rear和front之间保留一个空位,一旦rear在front的后一位那么说明为空,一旦rear在front的后两位那么说明已满。此时队列最多容纳的元素个数为s i z e − 1 size-1size1,队列中元素个数可以表示为( r e a r + 1 − f r o n t + s i z e ) (rear+1-front+size)%size(rear+1front+size).

2. C++实现

#include "Queue.h"

/*基于数组的循环队列实现 */
template <class E>
class AQueue : public Queue<E>
{
private:
    int size;     // 最大队列长度
    int front;    // 队首
    int rear;     // 队尾
    E *listArray; // 保存队列元素
public:
    AQueue(int defaultSize = 1000)
    {
        size = defaultSize;
        front = 0;
        rear = -1;
        listArray = new E[size];
    }
    ~AQueue() { delete[] listArray; listArray = NULL;}
    void clear();
    bool enqueue(const E &);    // 入队列
    bool dequeue(E &);          // 出队列
    bool frontValue(E &) const; // 队首元素
    int length() const;         // 队列元素个数
};

template <class E>
void AQueue<E>::clear()
{
    delete[] listArray;
    listArray = new E[size];
    front = 0;
    rear = -1;
}

template <class E>
int AQueue<E>::length() const
{
    return (rear + size - front + 1) % size ;
}

template <class E>
bool AQueue<E>::enqueue(const E &it)
{
    if (length() == size-1)
        return false;
    rear = (rear + 1) % size;
    listArray[rear] = it; 
    return true;
}

template <class E>
bool AQueue<E>::dequeue(E &it)
{
    if (length() == 0)
        return false;
    it = listArray[front]; 
    front = (front+1) % size; 
    return true; 
}

template<class E> 
bool AQueue<E>::frontValue(E &it) const 
{
    if (length() == 0)
        return false; 
    it = listArray[front]; 
    return true; 
}   


版权声明:本文为weixin_42710615原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。