















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An overview of queues as a data structure, their basic operations, and various applications. Queues are a first-in-first-out (fifo) or first-come-first-served (fcfs) structure, where items can only be removed from the front and added to the back. I/o buffers, scheduling queues, cpu scheduling, and array-based implementations.
Typology: Slides
1 / 23
This page cannot be seen from the preview
Don't miss anything!
















Docsity.com
Any implementation of a queue requires: storage for the data as well as markers (“pointers”) for the front and for the back of the queue.
An array-based implementation would need structures like myArray, an array to store the elements of the queue myFront, an index to track the front queue element myBack, an index to track the position following last queue element
Additions to the queue would result in incrementing myBack. Deletions from the queue would result in incrementing myFront. Clearly, we’d run out of space soon!
Solutions include: Shifting the elements downward with each deletion (YUCK!!) Viewing array as a circular buffer, i.e. wrapping the end to the front
Wraparound keeps the addition/deletion cycle from walking off the edge of the storage array.
Say, myArray has QUEUE_CAPACITY elements.
When myBack hits the end of myArray, a deletion should wrap myBack around to the first element of myArray, viz:
myBack++; if (myBack = = QUEUE_CAPACITY) myBack = 0;
//equivalently (preferred, concise) myBack = (myBack + 1) % QUEUE_CAPACITY;
Analogous handling of myFront needed.
#ifndef QUEUE #define QUEUE const int QUEUE_CAPACITY = 128; typedef int QueueElement; class Queue { /***** Function Members *****/ public: Queue(); bool empty() const; bool full() const; void addQ(const QueueElement & value); QueueElement front const(); //nondestructive “peek” void removeQ(); /***** Data Members *****/ private: QueueElement myArray[QUEUE_CAPACITY]; int myFront, myBack; }; // end of class declaration #endif
Queue::Queue() { myFront = myBack = 0; }
bool Queue::empty() { return myFront == myBack; }
bool Queue::full() { return myFront == (myBack + 1) % QUEUE_CAPACITY; }
Linked list implementation is another approach for queue representation.
The interface to the class Queue empty, addq, removeq, front, etc. would not change
The storage structure would be a linked list. The markers would be pointers now rather than indices into an array. myFront would contain the address of the first node in this list myBack would contain the address of the last node in this list
empty would test if myFront was a nonnull pointer, addq would allocate a new node, link it off myBack and update myBack, removeq would remove the first element and update myFront, front would return a copy of the element whose address was in myFront
A deque (double-ended queue) is similar to a queue BUT additions and deletions may be performed on either end.
Hence, an implementation needs a directive (tag) indicating at what end the operation is to be performed OR multiple methods should be provided.
We modify a queue's circular array implementation here.
#include
enum where {front, rear};
/* Deque implemented with same data members myArray myFront myBack Constructors and empty(), full() methods the same */ Docsity.com
//better to provide two addition methods void Deque::push_front(int item) {if ((myBack +1)% QUEUE_CAPACITY == myFront) cout << "FULL, cannot add to queue." << endl; else // enqueue at front { if (!myFront) myFront = QUEUE_CAPACITY; else myFront--; myArray[myFront] = item; } return; } void Deque::push_back(int item) { if ((myBack +1)% QUEUE_CAPACITY == myFront) cout << "FULL, cannot add to queue." << endl; else // regular enqueuing { myArray[myBack] = item; myBack = (myBack+ 1) % QUEUE_CAPACITY; } return; }
int Deque::pop_front() // assume non-empty { int item = myArray[myFront]; myFront= (myFront+ 1) % QUEUE_CAPACITY; return item; }
void Deque::pop_back() // assume non-empty { if (!myBack) myBack = QUEUE_CAPACITY; else myBack--; int item = myArray[myBack]; // dequeue from rear return item; }