笔记七:基于数组的循环队列的实现

本文详细介绍了队列这种线性表的基本概念及其三种常见的实现方式,并通过C++代码示例展示了队列的操作方法,包括插入、删除等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义队列也是一种线性表。其特点是队列的插入与删除在两端进行,是一个先进先出(FIFO)的线性表。插入元素的一端叫队尾,删除元素的一端叫队首。


三种表现形式:

1、

公式1: location(i)=i

——队列第i个元素映射到数组中,即为下标为i的元素,i>=0。
这里写图片描述


2、

公式2:location(i)=location(队首元素)+i

——队列第i个元素在数组中的位置只与队首元素有关,则删除一个队首元素时不需要吧元素左移,queueFront加1就好。因此可以解决1中的问题。
这里写图片描述


3、

公式3:location(i)=(location(队首元素)+i)% arrayLength

——把数组视为一个环,则2中出现的空间利用率不高的问题可以解决。

这里写图片描述

在1,2中queueFront=queueBack=-1,在3中对数组下标求余%,故初始状态queueFront=queueBack=0,若对图3中左上角数组继续插入一个元素D,假设可以插在下标为0处,则queueFront=queueBack,不能判断此时队列是空还是满,因此应空余一个空间给queueFront标识。即在初始化的空队列中,插入的第一个元素位于队列数组下标为1的位置,而不是0。每次插入一个新元素,queueBack=(queueBack+1)% arrayLength,是考虑到循环插入数组中。


代码:

#pragma warning(disable:4996)
#include<iostream>
using namespace std;

template<typename T>
class queue
{
public:
    virtual ~queue() {};
    virtual bool empty() const = 0;
    virtual int size() const = 0;
    virtual T& front() = 0; //返回头元素的引用
    virtual T& back() = 0;  //返回尾元素的引用
    virtual void pop() = 0; //删除首元素
    virtual void push(const T& theElement) = 0; //把元素加入队尾
};

template<typename T>
class arrayQueue : public queue<T>
{
public:
    arrayQueue(int initialCapacity = 10);
    ~arrayQueue() { delete[]  que; }

    bool empty() const { return queueFront == queueBack; }
    int  size() const;
    T&  front();
    T&  back();
    void pop();
    void push(const T& theElement);
private:
    T*  que;
    int queueFront; //首元素前一位置的下标
    int queueBack;  //尾元素的下标
    int arrayLength;
};

template<typename T> arrayQueue<T>::arrayQueue(int initialCapacity)
{
    if (initialCapacity < 0)
    {
        cout << "队列容量必须不小于0!" << endl;
        exit(-1);
    }

    que = new T[initialCapacity];
    queueFront = queueBack = 0;
    arrayLength = initialCapacity;
}

template<typename T> int arrayQueue<T>::size() const
{
    if (queueBack >= queueFront)
    {
        return queueBack - queueFront;
    }
    else{
        return arrayLength - queueFront - 1 + queueBack + 1;
    }
}

template<typename T> T& arrayQueue<T>::front()
{
    if (queueBack == queueFront)
    {
        cout << "队列为空,故不存在队首元素!";
        exit(-1);
    }
    return que[queueFront+1];
}

template<typename T> T& arrayQueue<T>::back()
{
    if (queueBack == queueFront)
    {
        cout << "队列为空,故不存在队尾元素!";
        exit(-1);
    }
    return que[queueBack];
}

template<typename T> void arrayQueue<T>::pop()
{
    if (queueBack == queueFront)
    {
        cout << "队列为空!";
        return ;
    }

    queueFront = (queueFront + 1) % arrayLength;
}

template<typename T> void arrayQueue<T>::push(const T& theElement)
{
    if ((queueBack + 1) % arrayLength == queueFront)    //容量已满,需扩充
    {
        T* newArray = new T[arrayLength * 2];

        //第一步,将从queueFront到arrayLength范围内的元素进行复制
        copy(que + queueFront + 1, que + arrayLength, newArray+1);

        //第二步,若queueBack < queueFront ,则进行剩余元素的复制
        if (queueBack<queueFront)
            copy(que, que + queueBack, newArray + 1 + arrayLength - queueFront - 1);

        //设置新的队首和队尾,队的容量
        queueFront = 0;
        queueBack = arrayLength -1;
        arrayLength = arrayLength * 2;
        delete[] que;
        que = newArray;
    }
    queueBack = (queueBack + 1) % arrayLength;  //新的队尾标识
    que[queueBack] = theElement;


}

int main(int argc, char* argv[])
{
    arrayQueue<int> AQ(6);
    cout << "将元素5插入队列中:" << endl;
    AQ.push(5);
    cout << "队首元素:" << AQ.front() << endl;
    cout << "队尾元素:" << AQ.back() << endl;
    cout << "队总元素:" << AQ.size() << endl;
    cout << endl;

    AQ.push(4);
    AQ.push(3);
    AQ.push(2);
    AQ.push(1);
    cout << "将元素4,3,2,1依次插入队列中:" << endl;
    cout << "队首元素:" << AQ.front() << endl;
    cout << "队尾元素:" << AQ.back() << endl;
    cout << "队总元素:" << AQ.size() << endl;
    cout << endl;

    AQ.pop();
    AQ.pop();
    AQ.pop();
    AQ.pop();
    AQ.push(6);
    AQ.push(7);
    cout << "删除4个队首元素,插入2个新元素后:" << endl;
    cout << "队首元素:" << AQ.front() << endl;
    cout << "队尾元素:" << AQ.back() << endl;
    cout << "队总元素:" << AQ.size() << endl;
    cout << endl;

    AQ.push(0);
    cout << "继续插入元素0:" << endl;
    cout << "队首元素:" << AQ.front() << endl;
    cout << "队尾元素:" << AQ.back() << endl;
    cout << "队总元素:" << AQ.size() << endl;

    return 0;
}

运行:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值