0% found this document useful (0 votes)
82 views

Queue:: Construct: Empty: Addq: Front: Removeq

This document discusses queues as a data structure. It defines queues as collections where items can only be removed from the front and added to the back. Basic queue operations like construct, empty, add, front, and remove are presented. Examples of queue uses include I/O buffers, print queues, and CPU scheduling. Array and linked list implementations of queues are described. The document also introduces double-ended queues (deques), which allow additions and removals from both ends.

Uploaded by

Shrey Khokhawat
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
82 views

Queue:: Construct: Empty: Addq: Front: Removeq

This document discusses queues as a data structure. It defines queues as collections where items can only be removed from the front and added to the back. Basic queue operations like construct, empty, add, front, and remove are presented. Examples of queue uses include I/O buffers, print queues, and CPU scheduling. Array and linked list implementations of queues are described. The document also introduces double-ended queues (deques), which allow additions and removals from both ends.

Uploaded by

Shrey Khokhawat
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 23

Chapter 5: Queues

Defn. As a data structure, a queue is an ordered collection of data


items with the property that items can be removed only at one
end, called the front of the queue, and items can be added only
at the other end, called the back of the queue. Basic operations
are: Queue:
Front: Remove ONLY
Back: Add ONLY

construct: Create an empty queue


empty: Check if a queue is empty
addQ: Add a value at the back of the queue
front: Retrieve the value at the front of the queue
Whereas aremoveQ: Remove the value
stack is a Last-In-First-Out at the
(LIFO) front ofathe
structure, queue
queue is a
First-In-First-Out (FIFO) or First-Come-First-Served (FCFS)
structure.
Examples: Input Buffer
a. I/O buffers: queues, scrolls, deques queues input for
 From a file: (queue) the CPU

Disk Memory

Input
Buffer
CPU

X
Infile >> X;
Interactively: (scroll — queue on one
end, stack on the other)
Scroll:
Keyboard Front: Remove ONLY
Back: Add
or
Remove (Backspace)
Memory
Backspace
Input
Buffer

X cin >> X;
Screen handling: (deque — double-
ended queue)
Scroll:
Front: Remove
or
Add
Back: Add
or
Remove
b. Scheduling queues in a multi-user
computer system:

 Printer queue: When files are submitted to a printer, they are
placed in the printer queue. The printer software executes
an algorithm something like:

for (;;)
{
while (printerQueue.empty())
sleep 1;
printFile = printerQueue.removeQ();
Print(printFile);
}
Other Queues:
1. Resident queue: On disk, waiting for memory
2. Ready queue: In memory — has everything it needs to run,
except the CPU
3. Suspended queue: Waiting for I/O transfer or to be reassigned the CPU

1
2

3
c. CPU Scheduling:
Probably uses a priority
queue: Items with lower
priority are behind all those
with higher priority.
(Usually a new item is
inserted behind those with the
same priority.)
Queues vs. Stacks
•Stacks are a LIFO container
•Store data in the reverse of order received
•Queues are a FIFO container
•Store data in the order received
•Stacks then suggest applications where some sort of reversal
or unwinding is desired.
•Queues suggest applications where service is to be rendered
relative to order received.
•Stacks and Queues can be used in conjunction to compare
different orderings of the same data set.
•From an ordering perspective, then, Queues are the “opposite”
of stacks
•Easy solution to the palindrome problem
Easy Palindrome Check
#include “Stack.h”;
#include “Queue.h”;
#include <iostream.h>
using namespace std;
int main(){
Stack S;
Queue Q;
char ch;
cout << “Enter string to be tested as palindrome: “;
while (cin >> ch){
S.push(ch);
Q.addq(ch);
}

bool pal = true;


while (!Q.empty() && pal) {
pal = Q.front() == S.pop();
Q.removeq();
}
if (pal)
cout << “Palindrome!!” << endl;
return 0;
}
Array Implementation
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
“Circular” Array-Implementation
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.


“Circular” Array-Implementation II
myBack: Incremented when an item is ADDED
myFront: Incremented when an item is REMOVED
• Initially, a queue object is empty.
 myFront = = 0
 myBack = = 0
• After many insertions and deletions, the queue is full
 First element, say, at myArray[i]
 myFront has value of i.
 Last element then at myArray[i-1] (i > 0)
 myBack has value of i.
• PROBLEM: How to distinguish between empty & full???
• Some Common Solutions:
1. Keep an empty slot between myFront and myBack,
 i.e., myArray uses QUEUE_CAPACITY - 1 elements
2. Keep an integer counter to track actual number of elements in queue
3. Keep a boolean full variable to keep track of if queue is full or not
QUEUE class
#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 class implementation
Queue::Queue()
{
myFront = myBack = 0;
}

bool Queue::empty()
{
return myFront == myBack;
}

bool Queue::full()
{
return myFront == (myBack + 1) % QUEUE_CAPACITY;
}
QUEUE class implementation II
void Queue::addQ(const QueueElement& value)
{
if (myFront != (myBack + 1) % QUEUE_CAPACITY)
{
myArray[myBack] = value;
myBack = (myBack + 1) % QUEUE_CAPACITY;
}
return;
}

void Queue::removeQ()
{
myFront = (myFront + 1) % QUEUE_CAPACITY;
}
Linked list implementation
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
Deque
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 <iostream>
using namespace std;

enum where {front, rear};

/* Deque implemented with same data members


myArray
myFront
myBack
Constructors and empty(), full() methods the same
*/
Deque enqueuing
void Deque::addQ(int item, where w)
{
if ((myBack +1)% QUEUE_CAPACITY == myFront)
cout << "FULL, cannot add to queue. Error!! "
<< endl;
else if (w == rear) // regular enqueuing
{
myArray[myBack] = item;
myBack = (myBack+ 1) % QUEUE_CAPACITY;
}
else // enqueue at front
{
if (!myFront)
myFront = QUEUE_CAPACITY;
else
myFront--;
myArray[myFront] = item;
}
return;
}
Deque enqueuing
//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;
}
Deque dequeuing
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;
}
deques
The deque is a standard container provided by STL.

It is easily implemented by the vector type.

See chapter 6 for more details.


Priority Queues
Priority queues are queues in which items are ordered by priority
rather than temporally (i.e. order in which received).

Any queue implementation then can be taken and modified to acquire


a priority queue.

The only needed modification is the addq() method.

Instead of unconditionally adding to the back, the queue must be


scanned for the correct insertion point.

An array implementation then would require shifting elements


(YUCK).

Hence a linked list implementation is preferred.


(Develop then the preferred solution after chapter 8)
Priority Queues
class PriorityQ
{
public:
PriorityQ();

void addq(int);
int removeq();

bool empty();
bool full();

int back();
int size();
private:
const int PRIORITYQ_CAPACITY = some_value;
int myArray[PRIORITYQ_CAPACITY];
int myFront;
int myBack;
};

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy