Data Structure BASICS (7): Data Structure Basics

Source: Internet
Author: User

Data Structure BASICS (7): Data Structure Basics

Queue

A queue is also a linear table with limited operations. It can be inserted only at one end of the table and deleted at the other end of the table. it is characterized by "first-in-first-out (FIFO)", which is also known as the first-out linear table, simple queue:

 

Cyclic queue

There is an inherent deficiency in the ordered queue, that is, the space utilization is not high, it will produce a "false overflow" phenomenon, that is: in fact, there is still free space in the queue to store elements, however, when we determine whether there is space in the queue, the queue tells us that the queue is full, so this overflow is not a real overflow, and there is still an empty location where elements can be placed in the data array, therefore, this is a "false overflow ";

So we introduced the concept of cyclic queue, and created a ring space in the ordered queue, that is, the table storing queue elements is logically considered as a ring, called a cyclic queue, it is as follows:


Note: As shown in, in order to facilitate implementation, our cyclic queue will have a free location, and the front pointer in m_front will always point to a location where the element value is null, therefore (m_front + 1) % capacity points to the first element of the team, while m_rear (rear in the figure) points to a actually existing team end element;

// Implementation and resolution of cyclic queue template <typename Type> class MyQueue {template <typename T> friend ostream & operator <(std: ostream & OS, const MyQueue <T> & queue); public: MyQueue (int queueSize = 64 );~ MyQueue (); void push (const Type & item); void pop () throw (std: range_error); const Type & front () const throw (std: range_error ); const Type & rear () const throw (std: range_error); bool isEmpty () const; private: Type * m_queue; int m_front; // first pointer (actually (m_front + 1) % capacity points to the first element) int m_rear; // last pointer int capacity; // memory size of the queue, but the actual available size is capacity-1 };
template <typename Type>MyQueue<Type>::MyQueue(int queueSize): capacity(queueSize){    if (queueSize < 1)        throw std::range_error("queueSize must >= 1");    m_queue = new Type[capacity];    if (m_queue == NULL)        throw std::bad_alloc();    m_front = m_rear = 0;}
template <typename Type>MyQueue<Type>::~MyQueue(){    delete []m_queue;    m_queue = NULL;    m_front = m_rear = 0;    capacity = -1;}
template <typename Type>inline bool MyQueue<Type>::isEmpty() const{    return m_front == m_rear;}
Template <typename Type> inline void MyQueue <Type>: push (const Type & item) {if (m_rear + 1) % capacity = m_front) // The queue is full {Type * newQueue = new Type [2 * capacity]; // The length of the new queue is twice that of the original queue if (newQueue = NULL) throw std :: bad_alloc (); int start = (m_front + 1) % capacity; // The starting address of the data sequence if (start <= 1) // The queue pointer has not been rewound {// you only need to copy it once: From the start point to the m_rear point to the element // std: copy (m_queue + start, m_queue + start + capacity-1, newQueue); std: copy (m_queue + start, m_queue + m_rear + 1, newQueue );} else {// copy twice // 1: From the element pointed to by start until the end of the array (not the queue) std: copy (m_queue + start, m_queue + capacity, newQueue); // 2: Starting from the array (not the queue) until the end of the queue std: copy (m_queue, m_queue + m_rear + 1, newQueue + capacity-start );} // reset the pointer position. For details, see the following illustration m_front = 2 * capacity-1; m_rear = capacity-2; capacity * = 2; delete [] m_queue; m_queue = newQueue;} // move the pointer behind the team end // Note: m_front + 1 may need to go back to m_rear = (m_rear + 1) % capacity; m_queue [m_rear] = item ;}
Template <typename Type> inline const Type & MyQueue <Type>: front () constthrow (std: range_error) {if (isEmpty ()) throw range_error ("queue is empty"); // Note: m_front + 1 may need to go back to return m_queue [(m_front + 1) % capacity];} template <typename Type> inline const Type & MyQueue <Type>: rear () constthrow (std: range_error) {if (isEmpty ()) throw range_error ("queue is empty"); return m_queue [m_rear];}
Template <typename Type> inline void MyQueue <Type>: pop () throw (std: range_error) {if (isEmpty () throw range_error ("queue is empty "); // Note: m_front + 1 may require m_front = (m_front + 1) % capacity; m_queue [m_front]. ~ Type (); // display the call to the destructor to destroy (the destructor) object}
// Output all the content of the queue for test template <typename Type> ostream & operator <(ostream & OS, const MyQueue <Type> & queue) {for (int I = (queue. m_front + 1) % (queue. capacity); I <= queue. m_rear;/** null **/) {OS <queue. m_queue [I] <''; if (I = queue. m_rear) break; else I = (I + 1) % (queue. capacity);} return OS ;}

Additional instructions

Two types of expansion operations when the queue is full:


Expanded Memory layout:

 

 

Appendix-test code:

Int main () {MyQueue <char> cQueue (3); cQueue. push ('A'); cQueue. push ('B'); // because the actual size of cQueue is 2, the array will be enlarged here. push ('C'); cout <cQueue <endl; cout <"front =" <cQueue. front () <", rear =" <cQueue. rear () <endl; cQueue. pop (); cQueue. pop (); cQueue. push ('D'); cQueue. push ('E'); cQueue. push ('F'); // m_rear of the queue will be rolled back to the cQueue. push ('G'); cQueue. pop (); cQueue. push ('H'); // when the queue is full, adding an element will expand the queue. // when m_rear is rewound, two copy operations (cQueue) will be triggered. push ('I'); // verify whether cout works properly <cQueue <endl; cout <"front =" <cQueue. front () <", rear =" <cQueue. rear () <endl; for (char ch = '1'; ch <= '9'; ++ ch) cQueue. push (ch); for (int I = 0; I <4; ++ I) cQueue. pop (); cout <cQueue <endl; cout <"front =" <cQueue. front () <", rear =" <cQueue. rear () <endl; return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.