隊列也是一種特殊的先進先出(FIFO)線性數據結構,數據能夠從一端進入,從另外一端出去。ios
隊列能夠利用數組和鏈表進行實現。git
/************************************************************************* > 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
/************************************************************************* > 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
/************************************************************************* > 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
/************************************************************************* > 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
/************************************************************************* > 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