【線性表(三)】:隊列之循環隊列

一、循環隊列的實現

template <class T>
class CyclicQueue:public Queue<T>
{
public:
    CyclicQueue():capacity_(10),
                  ptr_(shared_ptr<T>(new T[capacity_],[](T *p){delete[] p;})),
                  size_(0),
                  front_(ptr_.get()),
                  back_(ptr_.get()){}
    CyclicQueue(size_t capacity);
    ~CyclicQueue(){}

    //隊列是否爲空
    bool empty(){return size_==0;}
    //隊列的大小
    size_t size(){return size_;}
    //隊列容量大小
    size_t max_size(){return capacity_;}

    //返回隊首元素
    T front();
    //返回隊尾元素
    T back();
    //隊首彈出元素
    T pop();
    //隊尾添加元素
    void push(const T &value);

    //打印隊列
    void print();
private:
    void expend_capacity(const size_t &new_capacity);//動態擴容
private:
    shared_ptr<T> ptr_;
    T *front_;//隊列頭指針
    T *back_;//隊列尾指針
    size_t  size_;//隊列中存儲元素的個數
    size_t  capacity_;//隊列中最大存儲數量
};

template <class T>
CyclicQueue<T>::CyclicQueue(size_t capacity)
{
    if(capacity_<=0){
        cout<<"queue capacity must >0"<<endl;
        exit(0);
    }

    capacity_=capacity;
    size_=0;
    ptr_=shared_ptr<T>(new T[capacity_],[](T *p){delete[] p;});
    front_=back_=ptr_.get();
}

template <class T>
T CyclicQueue<T>::front()
{
    if(empty()){
        cout<<"CyclicQueue is empty!"<<endl;
        exit(0);
    } else{
        return *front_;
    }
}

template <class T>
T CyclicQueue<T>::back()
{
    if(empty()){
        cout<<"CyclicQueue is empty!"<<endl;
        exit(0);
    } else{
        return *back_;
    }
}

template <class T>
T CyclicQueue<T>::pop()
{
    if(empty()){
        cout<<"CyclicQueue is empty!"<<endl;
        exit(0);
    }

    T value=*front_;
    if(front_==ptr_.get()+capacity_-1){
        front_=ptr_.get();
    }else {
        ++front_;
    }
    --size_;
    return value;
}

template <class T>
void CyclicQueue<T>::expend_capacity(const size_t &new_capacity)
{
    shared_ptr<T> temp(new T[new_capacity],[](T *p){delete[] p;});

    copy(ptr_.get(),ptr_.get()+size_,temp.get());
    ptr_.swap(temp);
    front_ = ptr_.get();
    back_ = ptr_.get()+size_-1;
    temp.reset();
}

template <class T>
void CyclicQueue<T>::push(const T &value)
{
    if(size_==0)
    {
        *back_=value;
    }else if(size_==capacity_){//如果隊列已滿,需要進行擴容
        capacity_*=2;
        expend_capacity(capacity_);

        ++back_;
        *back_=value;
    }else{
        size_t distance=back_-ptr_.get();//獲取尾元素的位置
        size_t index=(distance+1)%capacity_;//獲取插入後元素的位置
        back_=ptr_.get()+index;
        *back_=value;
    }

    ++size_;
}

template <class T>
void CyclicQueue<T>::print()
{
    if(size_==0){
        return ;
    }
    size_t i=front_-ptr_.get();
    size_t j=back_-ptr_.get();
    while(true){
        int index=i%capacity_;
        if(index==j){
            break;
        }
        cout<<*(ptr_.get()+index)<<" ";
        ++i;
    }

    cout<<*back_<<endl;
}

參考鏈接:

隊列(循環隊列)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章