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

原文链接: https://www.cnblogs.com/HaroldC/p/12437425.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++泛化队列

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/333885

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午9:24
下一篇 2023年3月1日 下午9:24

相关推荐