Data Structure BASICS (7) -- Design and Implementation of cyclic queue

Source: Internet
Author: User

Data Structure BASICS (7) -- Design and Implementation of cyclic queue

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; <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD48cD48cHJlIGNsYXNzPQ = "brush: java;"> // implementation and parsing template of cyclic queue Class MyQueue {template Friend ostream & operator <(std: ostream & OS, const MyQueue & 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 
 
  MyQueue
  
   ::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 
 
  MyQueue
  
   ::~MyQueue(){    delete []m_queue;    m_queue = NULL;    m_front = m_rear = 0;    capacity = -1;}
  
 
template 
 
  inline bool MyQueue
  
   ::isEmpty() const{    return m_front == m_rear;}
  
 
Template
 
  
Inline void MyQueue
  
   
: 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: element directed from start to m_rear // 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: elements directed from start until the Array (not a queue) end 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 more information, see the figure m_front = 2 * capacity-1 below; m_rear = capacity-2; capacity * = 2; delete [] m_queue; m_queue = newQueue;} // move the team tail pointer behind. // note: m_front + 1 may require m_rear = (m_rear + 1) % capacity; m_queue [m_rear] = item ;}
  
 
Template
 
  
Inline const Type & MyQueue
  
   
: 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
   
    
Inline const Type & MyQueue
    
     
: Rear () constthrow (std: range_error) {if (isEmpty () throw range_error ("queue is empty"); return m_queue [m_rear];}
    
   
  
 
Template
 
  
Inline void MyQueue
  
   
: 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 testing template
 
  
Ostream & operator <(ostream & OS, const MyQueue
  
   
& 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
 
  
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.