队是先进先出的数据结构。需要一头一尾两个指针,front和rear。

template<class T>
class queue 
{
   public:
      virtual ~queue() {}
      virtual bool empty() const = 0;
                  // return true iff queue is empty
      virtual int size() const = 0;
                  // return number of elements in queue
      virtual T& front() = 0;
                  // return reference to the front element
      virtual T& back() = 0;
                  // return reference to the back element
      virtual void pop() = 0;
                  // remove the front element
      virtual void push(const T& theElement) = 0;
                  // add theElement at the back of the queue
};

ArrayQueue
这里采用循环数组存储。location(i)=(location(1)+i-1)%maxsize
循环数组初始化:front=rear=0
循环数组满:(rear+1)%maxsize=front
循环数组最大容量:maxsize-1

template<class T>
class ArrayStack:public queue 
{
    public:
        queue(int capacity=10){
            arrayLength=capacity;
            front=rear=0;
            element=new T[arrayLength];
        }
        int size(){
            return (rear-front+arrayLength)%arrayLength;
        }
        T& front(){
            return element[(front+1)%arrayLength];
        }
        T& back(){
            return element[rear];
        }
        void pop(){
            element[(front+1)%arrayLength].~T();
            front=(front+1)%arrayLength;
        }
        void push(const T& theElement){
            //这里在发现数组满的时候并没有采用change1Dlength函数,因为这个数组是循环
            //不能单纯的将数组元素从头到尾复制到新的数组,元素的起始位置可能在中间
            if(size()==arrayLength-1)
            {
                int start=(front+1)%arrayLength;
                T* newqueue=new T[arrayLength*2];
                if(start<2) //此时数组元素在循环数组中都是从头到尾
                {
                    copy(queue+start,queue+start+arraylenth-1,newqueue);
                }
                else 
                {
                    //copy(a,b,n)函数的复制的范围是[a,b)
                    copy(queue+start,queue+arrayLength,newqueue);
                    copy(queue,queue+rear+1,newqueue+arrayLength-start);
                }
                front=arrayLength*2-1;
                rear=arrayLength-2;//元素个数是arrayLength-1
                arrayLength*=2;
                queue=newqueue;
            }
            rear=(rear+1)%arrayLength;
            element[rear]=theElement;
        }
    private:
        //这里也不用定义数组元素大小的变量,可以通过front和rear来计算
        int front;
        int rear;
        T* element;
        int arrayLength;
}

LinkedQueue
这里写图片描述
可以使用链表来实现一个队列,此时需要两个变量front和rear来分别跟踪队列的两端,此时可能有两种情形:从front开始,链接到rear;或者从rear开始,链接到front。不同的链接方式元素删除和插入的难易程度不同,对于添加元素,两种方式的难易程度一样,但是对于删除元素,采用方式a更加方便。因此在用链表来实现队列的时候,我们采用方式a。

class LinkedQueue:public queue{
    public:
    linkedQueue(){
        front=NULL;
        rear=NULL;
        size=0;
    }
    ~linkedQueue(){
        while(front)
        {
             ListNode* node=front->next;
            delete front;
            front=node;
        }
    }
    void pop(){
        if(empty()) throw ...
        ListNode* node=front->next;
        delete front;
        front=node;
        size--;
    }
    void push(const T& theElement)
    {
        ListNode* node=new ListNode(theElement);
        if(empty()) front=node;
        else rear->next=node;
        rear=node;
        size++;
    }
    private:
        listNode* front;
        ListNode* rear;
        int size;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值