队列

队列的操作和栈比较类似,只不过是队列是先进先出的,同样只需要实现好顶层的接口,底层可以使用数组作为数据存储。

实现如下:

template <class T>
class ArrayQueue : public Queue<T>{
private:
    Array<T> *array;

public:
    ArrayQueue(int capacity){
        array=new Array<T>(capacity);
    }
    ArrayQueue(){
        array=new Array<T>(10);
    }
    ~ArrayQueue(){
        delete[] array;//这里的释放和栈类似的,可以参考栈的说明
        array=nullptr;
    }

    int getSize(){
        return array->getSize();
    }

    T dequeue(){
        return array->removeFirst();
    }

    T getFront(){
        return array->getFirst();
    }

    void enqueue(T e){
        array->addLast(e);
    }

    bool isEmpty(){
        return array->isEmpty();
    }

    /**
     * 打印数组的所有元素
     */
    void print() {
        std::cout << "Queue: size = " << array->getSize() << ", capacity = " << array->getCapacity() << std::endl;
        std::cout << "front ";
        array->toPrint();
        std::cout << " tail" << std::endl;
    }
};

循环队列
循环队列主要是添加了头指针front、尾指针tail,【注意】:tail指向的是最后一个元素的下一个位置,所以在申请空间时,会多要求一个用于tail指向。

关键点:
1)队列满了的条件:

(tail+1)%capacity==front

2)队列存放的元素个数:

(tail-front+capacity)%capacity

3)在进行添加和删除,以及扩容的过程中,front、tail的值的更新需要注意。

具体实现:

template <class T>
class LoopQueue : public Queue<T>{
private:
    T *data;
    int front,tail;//申请头指针、尾指针
    int capacity;

    void resize(int newCapacity){

        T *newData=new T[newCapacity+1];
        for(int i=0;i<getSize();i++){
            newData[i]=data[(i+front)%capacity];
        }
        data=newData;
        front=0;
        tail=getSize();
        capacity=newCapacity;
    }

public:
    LoopQueue(int capacity){
        data=new T[capacity+1];//多申请一个空间,因为尾指针是不存放数据的
        front=0;
        tail=0;//初始化尾指针也为0
        this->capacity=capacity;
    }
    LoopQueue(){
        data=new T[10];
        front=0;
        tail=0;
        capacity=10;
    }

    ~LoopQueue(){
        delete[] data;
        data= nullptr;
    }

    bool isEmpty(){
        return front==tail;
    }

    int getCapacity(){
        return capacity;
    }

    int getSize(){
        return (tail-front+capacity)%capacity;
    }

    void enqueue(T e){

        if((tail+1)%capacity==front){
            resize(capacity*2);
        }
        data[tail]=e;
        tail=(tail+1)%capacity;
    }

    T dequeue(){

        assert(front!=tail);
        T ret=data[front];
        front=(front+1)%capacity;
        if(getSize()==capacity/4&&capacity/2!=0){
            resize(capacity/2);
        }
        return ret;
    }

    T getFront(){
        assert(front!=tail);
        return data[front];
    }

    /**
        * 打印数组的所有元素
        */
    void print() {
        std::cout << "Queue: size = " << getSize() << ", capacity = " << capacity << std::endl;
        std::cout << "front [";
        for (int i = front; i != tail; i = (i + 1) % capacity) {
            std::cout << data[i];
            if ((i + 1) % capacity != tail) {
                std::cout << ", ";
            }
        }
        std::cout << "] tail" << std::endl;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值