zoukankan      html  css  js  c++  java
  • C++泛化队列

    队列

    队列也是一种特殊的先进先出(FIFO)线性数据结构,数据可以从一端进入,从另一端出去。

    队列可以利用数组和链表进行实现。

    抽象方法(ADTqueue.h)

    /*************************************************************************
    > File Name       : ADTqueue.h
    > Author          : Harold
    > Mail            : 2106562095@qq.com
    > Github          : www.github.com/Haroldcc
    > Created Time    : 2020年03月05日  10时38分59秒
    ************************************************************************/
    #ifndef ADTQUEUE_H_
    #define ADTQUEUE_H_
    
    /***** 队列的抽象数据类型 *****/
    
    template <typename T>
    class ADTqueue
    {
    public:
        virtual ~ADTqueue() {}
        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 &element) = 0; // 元素入队尾
    };
    #endif
    

    利用数组实现队列(arrayQueue.h)

    /*************************************************************************
    > File Name       : arrayQueue.h
    > Author          : Harold
    > Mail            : 2106562095@qq.com
    > Github          : www.github.com/Haroldcc
    > Created Time    : 2020年03月05日  10时48分43秒
    ************************************************************************/
    #ifndef ARRAYQUEUE_H_
    #define ARRAYQUEUE_H_
    
    /***** 运用数组实现队列 *****/
    #include "ADTqueue.h"
    #include "./myExceptions.h"
    #include <sstream>
    #include <iostream>
    
    template <typename T>
    class arrayQueue : public ADTqueue<T>
    {
    private:
        int m_front; // 队头
        int m_back;  // 队尾
        int m_arrayLength;
        T *m_queue;
    
    public:
        arrayQueue(int initialCapacity = 10);
        ~arrayQueue() { delete[] m_queue; }
    
        bool empty() const { return m_front == m_back; }
        int size() const { return (m_back - m_front + m_arrayLength) % m_arrayLength; }
        T &front()
        {
            if (m_front == m_back)
            {
                throw queueEmpty();
            }
            return m_queue[(m_front + 1) % m_arrayLength];
        }
        T &back()
        {
            if (m_front == m_back)
            {
                throw queueEmpty();
            }
            return m_queue[(m_front + 1) % m_arrayLength];
        }
        void pop()
        {
            if (m_front == m_back)
            {
                throw queueEmpty();
            }
            m_front = (m_front + 1) % m_arrayLength;
            m_queue[m_front].~T();
        }
        void push(const T &element);
    
        void output(std::ostream &out) const;
    };
    
    template <typename T>
    arrayQueue<T>::arrayQueue(int initialCapacity)
    {
        if (initialCapacity < 1)
        {
            std::ostringstream s;
            s << "初始化容量 = " << initialCapacity << "必须 > 0";
            throw illegalParameterValue(s.str());
        }
        m_arrayLength = initialCapacity;
        m_queue = new T[m_arrayLength];
        m_front = 0;
        m_back = 0;
    }
    
    template <typename T>
    void arrayQueue<T>::push(const T &element)
    {
        if ((m_back + 1) % m_arrayLength == m_front)
        { // 当容量不够时增加容量
            T *newQueue = new T[2 * m_arrayLength];
    
            // 将元素拷贝至newQueue
            int start = (m_front + 1) % m_arrayLength;
            if (start < 2)
            {
                std::copy(m_queue + start, m_queue + start + m_arrayLength - 1, newQueue);
            }
            else
            {
                std::copy(m_queue + start, m_queue + m_arrayLength, newQueue);
                std::copy(m_queue, m_queue + m_back + 1, newQueue + m_arrayLength - start);
            }
    
            m_front = 2 * m_arrayLength - 1;
            m_back = m_arrayLength - 2; // 队列size = arrayLength - 1
            m_arrayLength *= 2;
            m_queue = newQueue;
        }
        // 将元素放在队列的后面
        m_back = (m_back + 1) % m_arrayLength;
        m_queue[m_back] = element;
    }
    
    template <typename T>
    void arrayQueue<T>::output(std::ostream &out) const
    {
        out << "capacity = " << this->m_arrayLength << " size = " << size()
            << " front = " << this->m_front << ", [";
        for (int i = 0; i < this->m_arrayLength; i++)
        {
            if (i != 0)
                out << ", ";
    
            out << this->m_queue[i];
        }
        out << "]";
    }
    template <typename T>
    std::ostream &operator<<(std::ostream &out, const arrayQueue<T> &queue)
    {
        queue.output(out);
        return out;
    }
    
    #endif
    

    测试代码(testArrayQueue.cpp)

    /*************************************************************************
    > File Name       : testArrayQueue.cpp
    > Author          : Harold
    > Mail            : 2106562095@qq.com
    > Github          : www.github.com/Haroldcc
    > Created Time    : 2020年03月05日  13时34分44秒
    ************************************************************************/
    #include "arrayQueue.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        arrayQueue<int> q(4);
    
        q.push(1);
        q.push(2);
        q.push(3);
    
        for (int i = 0; i < 10; i++)
        {
            q.push(i + 1);
            q.push(i + 100);
        }
    
        cout << q << endl;
    
        cout << q.back() << endl;
        q.pop();
    
        cout << q.back() << endl;
        q.pop();
        cout << q.back() << endl;
        q.pop();
    
        return 0;
    }
    

    输出

    capacity = 32 size = 23 front = 31, [1, 2, 3, 1, 100, 2, 101, 3, 102, 4, 103, 5, 104, 6, 105, 7, 106, 8, 107, 9, 108, 10, 109, -1163005939, -1163005939, -1163005939, -1163005939, -1163005939, -1163005939, -1163005939, -1163005939, -1163005939]
    1
    2
    3
    

    利用链表实现队列(linkedQueue.h)

    /*************************************************************************
    > File Name       : linkedQueue.h
    > Author          : Harold
    > Mail            : 2106562095@qq.com
    > Github          : www.github.com/Haroldcc
    > Created Time    : 2020年03月05日  13时40分44秒
    ************************************************************************/
    #ifndef LINKEDQUEUE_H_
    #define LINKEDQUEUQ_H_
    
    #include "ADTqueue.h"
    #include "myExceptions.h"
    #include <sstream>
    
    /***** 运用链表实线队列 *****/
    
    template <typename T>
    struct Node
    {
        T element;
        Node<T> *next;
    
        Node() {}
        Node(const T &element) { this->element; }
        Node(const T &element, Node<T> *next)
        {
            this->element = element;
            this->next = next;
        }
    };
    
    template <typename T>
    class linkedQueue : public ADTqueue<T>
    {
    private:
        Node<T> *queueFront; // 队头指针
        Node<T> *queueBack;  // 队尾指针
        int queueSize;       // 队列元素个数
    
    public:
        linkedQueue(int initialCapacity = 10)
        {
            queueFront = nullptr;
            queueSize = 0;
        }
        ~linkedQueue();
        bool empty() const { return queueSize == 0; }
        int size() const { return queueSize; }
        T &front()
        {
            if (queueSize == 0)
            {
                throw queueEmpty();
            }
            return queueFront->element;
        }
        T &back()
        {
            if (queueSize == 0)
            {
                throw queueEmpty();
            }
            return queueBack->element;
        }
        void pop();
        void push(const T &);
    };
    
    template <typename T>
    linkedQueue<T>::~linkedQueue()
    {
        while (queueFront != nullptr)
        {
            Node<T> *nextNode = queueFront->next;
            delete queueFront;
            queueFront = nextNode;
        }
    }
    
    template <typename T>
    void linkedQueue<T>::pop()
    {
        if (queueFront == nullptr)
        {
            throw queueEmpty();
        }
    
        Node<T> *nextNode = queueFront->next;
        delete queueFront;
        queueFront = nextNode;
        queueSize--;
    }
    
    template <typename T>
    void linkedQueue<T>::push(const T &element)
    {
        // 创建新节点
        Node<T> *newNode = new Node<T>(element, nullptr);
    
        // 将新节点添加到队尾
        if (queueSize == 0)
            queueFront = newNode; // 队为空
        else
            queueBack->next = newNode; // 队不为空
        queueBack = newNode;
    
        queueSize++;
    }
    
    #endif
    

    测试(testLinkedQueue.cpp)

    /*************************************************************************
    > File Name       : testLinkedQueue.cpp
    > Author          : Harold
    > Mail            : 2106562095@qq.com
    > Github          : www.github.com/Haroldcc
    > Created Time    : 2020年03月05日  13时59分30秒
    ************************************************************************/
    
    #include "linkedQueue.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        linkedQueue<int> q(4);
    
        q.push(1);
        q.push(2);
        q.push(3);
    
        cout << q.front() << endl;
        q.pop();
    
        cout << q.front() << endl;
        q.pop();
        cout << q.front() << endl;
        q.pop();
    
        return 0;
    }
    
    
    // 输出
    1
    2
    3
    
  • 相关阅读:
    Repository中进行模糊查询
    Spring jpa添加查询条件
    java后端repository层中进行模糊查询
    MyBatis小白问题 1、Invalid bound statement (not found): com.itheima.dao.UserDao.findAll,2、Resources.getResourceAsStream()报错
    Date类型做加减运算
    时间格式转换
    mysql-支持的数据类型
    mysql—表的完整性约束
    数据库—表操作(第二章)
    mysql—使用python操作mysql数据库(第五章)
  • 原文地址:https://www.cnblogs.com/HaroldC/p/12437425.html
Copyright © 2011-2022 走看看