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