Loop two end queue
A special queue that can be used to enter and exit a queue at the beginning and end of a queue.
Circular double end queue is to make full use of space, using special data storage queue head and tail, here using array to achieve.
Circular double end queue (CircleQueue.h)
/************************************************************************* > File Name : CircleDeque.h > Author : Harold > Mail : 2106562095@qq.com > Github : www.github.com/Haroldcc > Created Time : 2020 March 7, 2015 13:21:25 ************************************************************************/ #ifndef CIRCLEQUEUE_H_ #define CIRCLEDEQUE_H_ #include <iostream> #include <sstream> #include "./myExceptions.h" /***** Loop two end queue*****/ /* Using array to realize * Double end queue: indicates that both the head and the tail can enter and leave the queue */ template <typename T> class CircleDeque { private: int front; // Team leader int size; // Number of elements in the team T *elements; // Array of implementation queues int m_capacity; // Array capacity // Verify the capacity of the array. Do you need to expand the array void ensureCapacity(int capacity); // The index in the incoming queue is mapped to get the index on the array int index(int index); public: // Constructor CircleDeque(int initialCapacity = 10); // Destructor ~CircleDeque() { delete[] this->elements; } int Size() const { return this->size; } bool isEmpty() const { return this->size == 0; } // End of the queue void enQueueRear(const T &element); // Team leader T deQueueFront(); // Team head in team void enQueueFront(const T &element); // Queue out T deQueueRear(); // Get team head T &head() const; // Get queue end T &tail() const; // Clear queue void clear(); // Output result void output(std::ostream &out) const; }; // Verify the capacity of the array. Do you need to expand the array template <typename T> void CircleDeque<T>::ensureCapacity(int capacity) { int oldCapacity = this->m_capacity; if (oldCapacity >= capacity) { return; } int newCapacity = oldCapacity + (oldCapacity >> 1); T *newElements = new T[newCapacity]; for (int i = 0; i < this->size; i++) { newElements[i] = elements[index(i)]; } delete[] this->elements; this->elements = newElements; this->front = 0; this->m_capacity = newCapacity; } // The index in the incoming queue is mapped to get the index on the array template <typename T> int CircleDeque<T>::index(int index) { index += this->front; if (index < 0) { return index + this->m_capacity; } return index % this->m_capacity; } // Constructor template <typename T> CircleDeque<T>::CircleDeque(int initialCapacity) { if (initialCapacity < 1) { std::ostringstream s; s << "Initialize capacity = " << initialCapacity << "Must > 0"; throw illegalParameterValue(s.str()); } this->front = 0; this->size = 0; this->elements = new T[initialCapacity]; this->m_capacity = initialCapacity; } // End of the queue template <typename T> void CircleDeque<T>::enQueueRear(const T &element) { ensureCapacity(this->size + 1); this->elements[index(this->size)] = element; this->size++; } // Team leader template <typename T> T CircleDeque<T>::deQueueFront() { T frontElement = this->elements[this->front]; this->elements[this->front] = 0; this->front = index(1); this->size--; return frontElement; } // Team head in team template <typename T> void CircleDeque<T>::enQueueFront(const T &element) { ensureCapacity(this->size + 1); this->front = index(-1); this->elements[this->front] = element; this->size++; } // Queue out template <typename T> T CircleDeque<T>::deQueueRear() { int rearIndex = index(this->size - 1); T rear = this->elements[rearIndex]; this->elements[rearIndex] = 0; this->size--; return rear; } // Get team head template <typename T> T &CircleDeque<T>::head() const { return this->elements[this->front]; } // Get queue end template <typename T> T &CircleDeque<T>::tail() const { return this->elements[index(this->size - 1)]; } // Clear queue template <typename T> void CircleDeque<T>::clear() { for (int i = 0; i < this->size; i++) this->elements[index(i)] = 0; this->size = this->front = 0; } // Output result template <typename T> void CircleDeque<T>::output(std::ostream &out) const { out << "capacity = " << this->m_capacity << " size = " << this->size << " front = " << this->front << ", ["; for (int i = 0; i < this->m_capacity; i++) { if (i != 0) out << ", "; out << this->elements[i]; } out << "]"; } template <typename T> std::ostream &operator<<(std::ostream &out, const CircleDeque<T> &queue) { queue.output(out); return out; } #endif
Test (testirclequeue. CPP)
/************************************************************************* > File Name : testCircleDeque.cpp > Author : Harold > Mail : 2106562095@qq.com > Github : www.github.com/Haroldcc > Created Time : 2020 March 7, 2015 15:49:27 ************************************************************************/ #include "CircleDeque.h" #include <iostream> using namespace std; int main() { CircleDeque<int> qu; // 8 7 5 4 2 1 101 102 104 105 106 107 108 109 tail for (int i = 0; i < 10; i++) { qu.enQueueFront(i + 1); qu.enQueueRear(i + 100); } cout << qu << endl; for (int i = 0; i < 3; i++) { qu.deQueueFront(); qu.deQueueRear(); } qu.enQueueFront(11); qu.enQueueFront(12); cout << qu << endl; while (!qu.isEmpty()) { cout << qu.deQueueFront() << endl; } return 0; }
output
capacity = 22 size = 20 front = 20, [8, 7, 6, 5, 4, 3, 2, 1, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -1163005939, -1163005939, 10, 9] capacity = 22 size = 16 front = 21, [11, 7, 6, 5, 4, 3, 2, 1, 100, 101, 102, 103, 104, 105, 106, 0, 0, 0, -1163005939, -1163005939, 0, 12] 12 11 7 6 5 4 3 2 1 100 101 102 103 104 105 106