zoukankan      html  css  js  c++  java
  • 队列的实现c++

    队列和上篇提到的栈类似,本质上都是特殊的线性表,它是在一端(队头)进行删除操作,另一端(队尾)进行插入操作,遵守先进先出的规则。。

    既然队列也是线性表,当然也有两种数据存储方式:

    顺序存储结构:这种结构事先要基本确定队列的大小,不支持动态分配存储空间,所以插入和删除元素比较省时,但是会造成空间的浪费。

                         为了节省空间,这里引入了循环队列,本质上也是顺序存储结构。

    链式存储结构:可以不需要事先知道队列的大小,支持动态和释放空间,但是插入和删除操作比较耗时,也称链队列

    建议:当事先基本上确定队列的大小,且插入和删除操作比较频繁时,优先考虑循环队列。。

    1.循环队列实现:

    头文件声明和定义放一块了,只实现了基本的操作,不是很完善,等看了源码再改。。

    头文件:在Queue.h头文件中

    #ifndef QUEUE_H
    #define QUEUE_H
    #include<cassert>
    #include<iostream>
    using namespace std;
    template<typename T>
    class Queue
    {
    public:
        Queue(int maxsize = 10);
        Queue(const Queue<T>& rhs);
        Queue<T>& operator=(const Queue<T>& rhs);
        ~Queue();
    public:
        bool empty() const;
        bool IsFull() const;
        int size() const;
    
        void push(const T& data);
        void pop();
        T& front();
        T   front() const;
        T& back();
        T   back() const;
    private:
        T *array;
        int Front;
        int rear;
        int capacity;
    };
    
    template<typename T>
    Queue<T>::Queue(int maxsize) :Front(0), rear(0),capacity(maxsize)
    {
        array = new T[maxsize];
        assert(array != NULL);    //存储分配失败则退出;
    }
    
    template<typename T>
    Queue<T>::Queue(const Queue<T>& rhs) :Front(rhs.Front), rear(rhs.rear),capacity(rhs.capacity)
    {
        array = new T[capacity];
        for (int i = 0; i != (this->size()); i++)
            array[i] = rhs.array[i];
    }
    
    template<typename T>
    Queue<T>& Queue<T>::operator=(const Queue<T>& rhs)
    {
        if (this != &rhs)
        {
            delete[] array;
            capacity = rhs.capacity;
            Front = rhs.Front;
            rear = rhs.rear;
            array = new T[capacity];
            for (int i = 0; i != (this->size()); i++)
                array[i] = rhs.array[i];
        }
        return *this;
    }
    template<typename T>
    Queue<T>::~Queue()
    {
            delete[] array;
    }
    
    template<typename T>
    bool Queue<T>::empty() const
    {
        return Front == rear;      //此处为循环队列,当front==rear时为空。
    }
    
    template<typename T>
    bool Queue<T>::IsFull() const
    {
        return(rear + 1) % capacity == Front;   //当(rear+1)%capacity==front为满,因为为满时差一个元素,但是可能rear>front,也可能rear<front.
    }
    
    template<typename T>
    int Queue<T>::size() const
    {
        return (rear - Front + capacity) % capacity;
    }
    
    template<typename T>
    void Queue<T>::push(const T& data)
    {
        if (!IsFull())
        {
            array[rear] = data;
            rear = (rear + 1) % capacity;
        }
        else                                                  //当队列满了之后可进行扩容
        {
            T *newarray=new T[ 2*capacity ];
            for (int i = 0; i != 2*capacity&&!this->empty(); i++)
            {
                newarray[i] =this-> front();
                this->pop();
            }
            delete [ ] array;
            array = newarray;
            Front = 0;
            array[rear] = data;
            rear =this->rear+1;
            capacity = 2*capacity;
        }
    }
    
    template<typename T>
    void Queue<T>::pop()
    {
        if (!empty())
        {
            //array[Front].~T();   //将队头元素析构掉
            Front = (Front + 1) % capacity;
        }
        else
            cout<<"empty queue!"<<endl;
    }
    
    template<typename T>
    T& Queue<T>::front()
    {
        if (empty())
            cerr << "Error, queue is empty!";
        return array[Front];
    }
    template<typename T>
    T Queue<T>::front() const
    {
        if (empty())
            cerr << "Error, queue is empty!";
        return array[Front];
    }
    template<typename T>
    T& Queue<T>::back()
    {
        if (empty())
            cerr << "Error, queue is empty!";
        return array[rear-1];                             //rear类似与尾后指针
    }
    template<typename T>
    T Queue<T>::back() const
    {
        if (empty())
            cerr << "Error, queue is empty!";
        return array[rear-1];
    }
    #endif // QUEUE_H

    测试代码:

     网上找的代码:

    #include<iostream>
    #include"Queue.h"
    using namespace std;
    
    int main()
    {
        Queue<int> q(10); //声明队列
        int n;
        cin >> n;
        for (int i = 0; i<n; i++)
            q.push(i + 1);
        while (!q.empty())
        {
            cout << q.front() << " ";
            q.pop();
            if (!q.empty()) //此处需要判断此时队列是否为空
            {
                q.push(q.front());
                q.pop();
            }
        }
        cout << endl;
        return 0;
    }

    2.链队列的实现:

    头文件:

     在Queue1.h头文件中

    #ifndef QUEUE_H1
    #define QUEUE_H1
    /**********在队头删除节点,队尾添加节点*************/
    #include<iostream>
    using namespace std;
    template<typename T>
    class Queue
    {
    public:
        Queue();
        ~Queue();
        bool empty() const;
        int size() const;
        void clear();
        void push(const T & node);
        void pop();
        T&  front();
        T   front() const;
    private:       //也可以直接用来链表list直接构造
        struct  QueueNode
        {
            T data;
            QueueNode* next;
            QueueNode(const T& Newdata, QueueNode* nextnode=NULL) :data(Newdata), next(nextnode)
            { }
           // QueueNode() = default;
        };
        QueueNode * Front;  //队头指针
        QueueNode * rear;  // 队尾指针
        int count;
    };
    //此处不设头节点
    template<typename T>
    Queue<T>::Queue() :Front (NULL),  rear (NULL), count(0)
    {}
    template<typename T>
    Queue<T>::~Queue()
    {
        clear();
    }
    template<typename T>
    void Queue<T>::push(const T & node)
    {
        if(Front==NULL)
            Front=rear=new QueueNode(node);
        else
        {
         QueueNode * newqueuenode = new QueueNode(node);
        rear->next = newqueuenode;
        rear = newqueuenode;
        }
        count++;
    }
    template<typename T>
    bool Queue<T>::empty() const
    {
        return Front==NULL;
    }
    
    template<typename T>
    int Queue<T>::size() const
    {
        return count;
    }
    
    template<typename T>
    void Queue<T>::clear()
    {
        while (Front)
        {
            QueueNode * FrontofQueue = Front;
            Front = Front->next;
            delete FrontofQueue;
        }
        count = 0;
    }
    
    template<typename T>
    void Queue<T>::pop()
    {
        if (empty())
        {
            cerr << "Error, queue is empty!";
        }
        QueueNode * FrontofQueue = Front;
        Front = Front->next;
        delete FrontofQueue;
        count--;
    }
    
    template<typename T>
    T& Queue<T>::front()
    {
        if (empty())
        {
            cerr << "Error, queue is empty!";
        }
        return Front->data;
    }
    
    template<typename T>
    T Queue<T>::front() const
    {
        if (empty())
        {
            cerr << "Error, queue is empty!";
        }
        return Front->data;
    }
    #endif // QUEUE_H1

    测试代码:

    #include<iostream>
    #include"Queue1.h"
    using namespace std;
    
    int main()
    {
        Queue<int> q; //声明队列
        int n;
        cin >> n;
        for (int i = 0; i<n; i++)
            q.push(i + 1);
        while (!q.empty())
        {
            cout << q.front() << " ";
            q.pop();
            if (!q.empty()) //此处需要判断此时队列是否为空
            {
                q.push(q.front());
                q.pop();
            }
        }
        cout << endl;
        return 0;
    }

    两种方法运行结果是一样的。。

  • 相关阅读:
    HDU 4825 字典树
    HDU4287 字典树
    HDU 3973 AC's String 字符串哈希
    HDU5296 Annoying problem(LCA)
    Gym 100712L Alternating Strings II(单调队列)
    数据结构专题
    HDU5033 Building(单调栈)
    HDU2888 Check Corners(二维RMQ)
    HDU 4123 Bob’s Race(RMQ)
    HDU3530 Subsequence(单调队列)
  • 原文地址:https://www.cnblogs.com/liuamin/p/6547253.html
Copyright © 2011-2022 走看看