0% found this document useful (0 votes)
36 views65 pages

Queues

The document discusses different types of queues and their implementations. It describes queues as a linear data structure where elements are added to one end and removed from the other. Common queue operations like enqueue and dequeue are explained. Methods for implementing queues using arrays and linked lists are provided.

Uploaded by

vs0773144
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views65 pages

Queues

The document discusses different types of queues and their implementations. It describes queues as a linear data structure where elements are added to one end and removed from the other. Common queue operations like enqueue and dequeue are explained. Methods for implementing queues using arrays and linked lists are provided.

Uploaded by

vs0773144
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 65

Queues

Paper: Data Structures


Unit No : II, Linear Structures,
Lesson: Queues
Lesson Developer : Vandana Kalra, Associate Professor
College/Department: College of Vocational Studies , University of
Delhi

Institute of Lifelong Learning, University of Delhi 1


Queues

Table of Contents
3: Queue
3.1: Introduction
3.2: Operations on Queue
3.3: Software Queue
3.3.1: Implementation of queue
3.3.1.1: Linear Representation
3.3.1.2: Queue Representation using two stacks
3.3.1.3: Linked representation
3.3.1.4: Comparing two implementations of Queue representation
3.3.2: Generic queue
3.4: Circular Queue
3.5: Deque
3.6: Priority Queue
3.7: Queue: Application
3.7.1: Queue as scheduling queue
3.7.2: Queue as Buffering queue
3.7.3: Queue- search space Exploration
3.7.4: circular queue in real life
3.7.5: Application of priority Queue
3.7.6: Message Queue
3.7.7: The M/M/1 Queue
Summary
Exercises
Glossary
References

3 Queue
As discussed in previous section, stack is an abstract data structure with the special
property that elements are always added to and removed from the top. We know many
areas where we have to refer the data elements in different manner. Queue is another
abstract data structure where elements are referred in different order.

Institute of Lifelong Learning, University of Delhi 2


Queues

3.1 Introduction
Queue is a linear data structure in which data can be added to one end and retrieved
from the other. Just like the queue of the real world, the data that goes first into the
queue is the first one to be retrieved. That is why queues are also called as First-In-
First-Out list.

In real time application, we use this data structure in many situations. For example ,
line of students on a fee counter in a college to pay the fees is an example of queue.
Another common example is to make a line of commuters waiting at a bus stop for a
bus. There are several other situations also where queue is used so that addition takes
place only at the rear and deletion only at front.

Fig 3.1: Queue at Bus Stop

Source: haldolongwidget.files.wordpress.com/2008/12/bus-queue.jpg

Institute of Lifelong Learning, University of Delhi 3


Queues

Source: ortiznellengraceit123.blogspot.com/
Fig 3.2: Building a queue

Value addition: Pictorial representation


Queue principle : First In First Out

Source: http://www.lean-academy.com/web/Lean_Ausbildung/Lean_Expert/107/120/127/67.html

3.2 Operations on Queue


We saw that in stack data is inserted and retrieved both from one end but in case of
Queues; data is added to one end and retrieved from the other end .

The data last added in the stack is the first one to be retrieved while in case of queues,
the data first added is the first one to be retrieved. The terms used in representation of
queue are

1. Rear: A variable indicating the end where new data will be added (in the
queue).

Institute of Lifelong Learning, University of Delhi 4


Queues

2. Front: It is a variable indicating the end from where the data will be retrieved .

OPERATIONS DESCRIPTION
Create To create an initial queue.

Destroy To remove queue from memory. This task is accomplished


using a destructor.
Enqueue Insert an element at the rear of the list.
Dequeue Access and remove the front element from the queue.
Peep Access the front element of the queue without removing it
from the queue.
isFull Check whether the queue is full.
IsEmpty Check whether the queue is empty.

Table 3.1 Queue Operations

Create: This operation creates a initial empty queue with two pointers front and rear
pointing to their initial values.

Destroy: This operation destroys queue by deleting all elements from the queue.

Enqueue: This operation allows to add the element from the end of the queue known
as rear .This also reflect the change in the rear pointer. If queue is empty, adding an
element moves both the pointers front and rear.

Dequeue: This operation allows deletion of an element from the end known as front.
This changes the front pointer to reflect deletion. If queue is empty ,no elements will
be deleted and both pointers points to their initial values. If queue has one element,
deletion of this element makes front and rear pointing to same initial value. Dequeue
retrieves and removes the front element from the queue.

Peep: This operation allows to retrieve the front element from the queue . It will not
remove the element while retrieving as Dequeue operation does.

IsFull : It checks whether the queue is full or not by checking the pointers rear and
front.

Isempty: It checks whether the queue is empty or not by checking the pointers rear
and front.

Institute of Lifelong Learning, University of Delhi 5


Queues

Fig 3.3 : Simple Representation of Queue

Source :Wikipedia.org

Value addition: Pictorial representation


Queue operations: Enqueue and Dequeue

Source: http://www.javacoffeebreak.com/books/extracts/javanotesv3/c11/queue.gif

Institute of Lifelong Learning, University of Delhi 6


Queues

Process of adding and retrieving data in the queue will change the positions of pointers
Font and Rear. To illustrate this let us discuss one example.

Suppose we have a queue represented by an array queue [10], which is empty to start
with. The values of front and rear variable upon different actions are mentioned in {}.

queue =EMPTY {front=-1, rear=0}

enqueue (‘a ‘)

Now, queue = ‘a ‘ {front=0, rear=1}

enqueue (‘b’)

Now, queue = ‘a’, ’b’ {front=0, rear=2}

dequeue () [ It returns ‘a’ ]

Now, queue = ‘b ‘ {front=1, rear=2}

In this way, a queue like a stack, can grow and shrink over time.

Source: http://codefords.wordpress.com

Fig 3.4 : Movement of pointers Front and Rear

Institute of Lifelong Learning, University of Delhi 7


Queues

Queue Algorithms: enqueue and dequeue

Procedure enqueue(Q,front,rear,item) : This procedure inserts an element item to the


rear of the queue which is represented by a vector Q consisting n elements with a
pointer rear denoting the back of the queue.
STEP 1 : [Check for queue overflow]
If (rear=n+1)
then write(queue full)
Return
STEP 2 : [Insert element]
Q[rear] <-- item
STEP 3 : [Increment rear]
rear <-- rear+1
STEP 4 : [Finished]
Return
The first step of this algorithm checks for an overflow condition. If such a condition
exists, then the insertion can't be performed and an appropriate error message results.

Procedure Dequeue(Q, front, rear, item) : This procedure removes an element from the
front end of the queue Q and return back through item.
STEP 1 : [Check for the underflow on stack]
If (front=rear)
then write(Queue empty)
Return
STEP 2 : [Hold the former front element of queue into item]
item <-- Q[front]
STEP 3 : [increment the front pointer or index by 1]
front <-- front+1
STEP 4 : [finished-Return the retrieved item from the queue]
Return(item)
As Underflow condition is checked for in the first step of the algorithm. If such a
condition exists, then the deletion cannot be performed and an appropriate error
message results.

Procedure Display(Q, front) : This procedure displays the contents of the queue i.e.,
vector Q.
STEP 1 : [check for empty on queue]
if (front=rear)
then write('queue empty')
Return
STEP 2 : [Repeat through STEP 3 from i=TOP to 0]
Repeat through STEP 3 for i=front to rear-1 STEP 1]
STEP 3 : [Display the queue content]
write (Q[i])
STEP 4 : [Finished]
Return
The first step of this algorithm checks for an empty condition. If such a condition exists,
then the contents of the queue cannot be displayed and an appropriate error message
results

Institute of Lifelong Learning, University of Delhi 8


Queues

3.3 Implementation of Queues


Queue can also be used in software as stack is. They are implemented in many high
level languages like C,C++, Java etc. In the program, we can use only two operations
enqueue and dequeue. They are implemented in high level language with two
representations linear and linked.

3.3.1 Linear Representation

Linear representation of queue can be using an array or vector. To implement a Linear


queue we need a class Queue having two variables, called front and rear as member
data, that holds the index of the first and the last element stored in the queue and an
array ,named arr to hold the maximum 10 elements of the queue.

Now have a look at the following example program that illustrates all this in C++:

// -- A Queue Class in C++ --


// example program in C++ to illustrate queues represented by arrays
#include<iostream.h>

// macro to hold the max number of elements in the queue


#define MAX 10

// queue class
class queue
{
int arr[MAX];
int front, rear;

public:
queue();
void enqueue(int);
int dequeue(void);

};
// queue class ends

// member functions
queue::queue() //constructor
{
// initialize index
// variables
front=-1;
rear=0;
}

void queue:: enqueue(int data)// function to add element


{

Institute of Lifelong Learning, University of Delhi 9


Queues

if(rear==MAX-1)
{
cout<<"QUEUE FULL!";
return;
}

arr[rear]=data;
// increase index
// variable
rear++;

if(front=-1)
front=0;
}

int queue::dequeue() // function to retrieve element


{
int data;

if(front==-1)
{
cout<<"QUEUE EMPTY!";
return NULL;
}

data=arr[front];
arr[front]=0;

// if both index variables


// point to the same location
// then start afresh
if(front==rear-1)
{
front=-1;
rear=0;
}
else
front++;

return data;
}
// member functions ends

void main(void) // Main function calling member functions


{
queue obj;
int ch;
int num;

while(ch!=3)
{

Institute of Lifelong Learning, University of Delhi 10


Queues

cout<<"1> ADD";
cout<<"\n2> RETRIVE";
cout<<"\n3> QUIT\n";

cin>>ch;

switch(ch)
{
case 1:
cout<<"enter element:";
cin>>num;

obj.enqueue(num);
break;

case 2:
cout<<"\n\nRetrieved: ";
cout<<obj.dequeue();
cout<<"\n\n";
break;
}
}
}

Another problem with the Linear queue is If the last position of the queue is occupied,
it is not possible to enqueue any more elements even though some positions are
vacant towards the front positions of the queue.
However, this limitation can be overcome by moving the elements forward, such that
the first element of the queue goes to position with index 0, and the rest of the
elements move accordingly. And finally the front and rear variables are adjusted
appropriately. The modified version of functions enqueue and dequeue to take care this
shifting are :

Dequeue()

int queue::dequeue()
{ int data;

if(front==-1)
{
cout<<"QUEUE EMPTY!";
return NULL;
}

else
{ data=arr[front];
arr[front]=0;

Institute of Lifelong Learning, University of Delhi 11


Queues

// if both index variables


// point to the same location
// then start afresh

if(front==rear-1)
front=-1;
rear=0;
else
front++;
// this loop shifts the data from queue last positions to the beginning to make
// space for more data at the end
int k=0;
for(int i=front;i<=rear;i++)
{
arr[k]=arr[i];
k++;

}
front=0;
rear=k-1;
}
return data;
}

Enqueue()

void queue::enqueue(int data)


{
if(rear==Max-1)
cout<<"OVERFLOW>>>>>";
else
{ if(front==-1)
{ front =0;}
arr[rear]=data;
rear++;

3.3.2 Implementing Queue using two stacks

We can implement a FIFO queue using two stacks. Lets call the stacks Instack and
Outstack. An element is inserted in the queue by pushing it into the Instack. An

Institute of Lifelong Learning, University of Delhi 12


Queues

element is extracted from the queue by popping it from the Outstack. If the Outstack is
empty then all elements currently in Instack are transferred to Outstack but in the
reverse order. stack1.)

Let us see how this will be implemented:

Queue is First in First Out


Stack is Last in First Out.

Initialize two stack, say instack and outstack with limit 2.


Let our data is 1 & 2.

we are going to push 1 & 2 one by one to Stack.


If it is Queue the Output will be 1 & 2.

steps:

a. Put 1 to instack [instack - 1, ][outstack - , ]

b. Put 2 to instack [instack - 1, 2][outstack - , ]

c. Out instack (instack will push the last elemet ie 2) [instack - 1, ][outstack - , ]

d. Put the result of 'c' to outstack (now 2 will be stored in outstack)


[instack - 1, ][outstack - 2, ]

e. Out instack(Now instack will push the remaining element ie 1)


[instack - , ][outstack - 2 , ]

f. Put the result of 'e' to outstack (now 1 will be stored in outstack)


[instack - , ][outstack - 2 , 1]

g. Out outstack (since the Last element is 1,B will push 1 out)
[instack - , ] [outstack- 2, ]

h. Display the Result of 'g' ... Out Put : 1

i. Out outstack (outstack will push the remaining element ie 2 out)

[instack - , ][outstack- , ]
j. Display the Result of 'g' ... Out Put : 1 2

Thus the Output will be the same as Queue

Institute of Lifelong Learning, University of Delhi 13


Queues

Source: http://keithblue1984.spaces.live.com/blog/
Fig 3.5: Implementation of queue using two stacks

Institute of Lifelong Learning, University of Delhi 14


Queues

Value addition: Do you Know

How to implement stack using Queue?

Given two queues with their standard operations (enqueue, dequeue, isempty,
size), implement a stack with its standard operations (pop, push, isempty,
size).There should be TWO versions of the solution.s

 Version A: The stack should be efficient when pushing an item.


 Version B: The stack should be efficient when popping an item

Version A:
push:
 enqueue in queue1
pop:
 while size of queue1 is bigger than 1, pipe dequeued items from queue1
into queue2
 dequeue and return the last item of queue1, then switch the names of
queue1 and queue2
Version B:
push:
 enqueue in queue2
 enqueue all items of queue1 in queue2, then switch the names of queue1
and queue2
pop:
 deqeue from queue1
 s
Following diagram shows the working according to the version B.
Step 0: initial empty stack and queues
Step 0:
"Stack"

+---+---+---+---+---+

| | | | | |

+---+---+---+---+---+

Queue A Queue B

+---+---+---+---+---+ +---+---+---+---+---+

| | | | | | | | | | | |

+---+---+---+---+---+ +---+---+---+---+---+

Step 1: Enqueue in queue B , enqueue all elements in queue B from A. swap the names of

Institute of Lifelong Learning, University of Delhi 15


Queues

queues. Step 1:

"Stack"

+---+---+---+---+---+

| 1 | | | | |

+---+---+---+---+---+

Queue A Queue B

+---+---+---+---+---+ +---+---+---+---+---+

| 1 | | | | | | | | | | |

+---+---+---+---+---+ +---+---+---+---+---+

Step 2: Enqueue(2) in queue B and enqueue (1) from queue A to queue B. swap the names of
queue.

Step 2:

"Stack"

+---+---+---+---+---+

| 2 | 1 | | | |

+---+---+---+---+---+

Queue A Queue B

+---+---+---+---+---+ +---+---+---+---+---+

| | | | | | | 2 | 1 | | | |

+---+---+---+---+---+ +---+---+---+---+---+

Step 3: enqueue(3) in queue B , enqueue(2) and enqueue(1) in Queue B from

Institute of Lifelong Learning, University of Delhi 16


Queues

Queue A. swap the names of queues. Queue A contains 3 2 1.

Then dequeue()=3 from queue A which is the last element entered in the queue.
They work on stack principle “LIFO”.

Step 3:

"Stack"

+---+---+---+---+---+

| 3 | 2 | 1 | | |

+---+---+---+---+---+

Queue A Queue B

+---+---+---+---+---+ +---+---+---+---+---+

| 3 | 2 | 1 | | | | | | | | |

+---+---+---+---+---+ +---+---+---+---+---+

This idea is to simulate LIFO by having data structures that works in FIFO order.

Source:http://stackoverflow.com/questions/688276/implement-stack-using-two-
queues(modified-self)

3.3.3 Linked Representation

The array based linear representation of Queue sometimes called Bounded queue
because it has many limitations .They are illustrated below:
1. Size of the Queue must be known in advance. It is fixed in size.
2. There are many real or system maintaining situations when an attempt to
add an element cause overflow. However, queue, as an abstract data structure
cannot be full .Hence abstractly, it is always possible to add an element in
queue. Therefore, representing data structure queue as an array prohibits the
growth of queue beyond the finite number of elements.
Therefore , some dynamic structure should be required to represent queue.

A Queue which is represented using a linked list is also known as linked queue. Linked
queue can be represented as singly linked list and doubly linked list with two pointer
variables front and rear. The linked representation allow a queue to grow to a limit of
the computer’s memory. The class structures for linked queue is as follows. Node of
linked list in the class have integer element info and next is a pointer pointing to next

Institute of Lifelong Learning, University of Delhi 17


Queues

element. Class queue contains pointer front and rear pointing to first and last element
of linked list respectively and also all related operations as member functions . The
addatrear(enqueue) and deleteatfront (dequeue) operations are exactly same except
list is maintained by next pointer. Traverse operation prints all the elements from the
queue.

//Program to demonstrate the implementation of various operations on A QUEUE


USING A LINEAR LINKED LIST
#include<iostream.h>
#include<conio.h>
class node
{ public:
int info;
node *next;
node()
{ next=0; }
node(int a, node *y=0)
{
info=a;
next=y;
}
};
class queue
{ node *front,*rear;
public:
queue()
{front=rear=0;
}
void addatrear(int ele);
int deleteatfront();
void traverse();
};

int queue:: deleteatfront()


{ node *t;
t=front;
int m=t->info;
if(front==rear)
{front=rear=0;
}
else

Institute of Lifelong Learning, University of Delhi 18


Queues

{
front=front->next;
}
delete t;
return m;

void queue::addatrear(int ele)


{ node *p;
p=new node(ele);
if(front==0)
{
front=rear=p;

else
{
rear->next=p;
rear=p;

}
void queue::traverse()
{
node *q;
q=front;
cout<<"Entered info is......";
while(q!=rear->next)
{ cout<<q->info<<" ";
q=q->next;

}
void main()
{
clrscr();
queue v;
int e;
char ch;

Institute of Lifelong Learning, University of Delhi 19


Queues

do
{
cout<<"\nEnter the node....";
cout<<"\nEnter the info.....";
cin>>e;
v.addatrear(e);
cout<<"want to enter more elements..(y/n)....";
cin>>ch;
}while(ch=='y'||ch=='Y');
v.traverse();
int n=v.deleteatfront();
v.traverse();
getch();
}

The deleteatfront (dequeue) operation deletes the first node pointed by front
from the linked list by performing the following task:

 Store the front in some temporary pointer


 Store the information of front element in some variable
 Check whether list contain only one element if so, initialize front and
rear pointer to null.
 Otherwise, change the front pointer to the second element of linked list
 Free the node pointed by temporary pointer

The addatrear(enqueue) operation adds the new node in the beginning of linked
list by performing the following tasks:

 Create the new node using the variable passed as an argument


 Check the queue is empty or not
 If queue is empty, the new node pointer becomes the front and rear of
the list.
 If queue is not empty, the current rear->next should point to new node
and the next pointer of new node should have null.
 Then new node becomes the new rear pointer.

The traverse operation will print all the information from the nodes of the list by
performing the following task:

 Start the traverse by node pointed by front


 Use the loop to print the information of each node until it reaches the
rear pointer
 After printing the information of the current node , advance the pointer
to the next node using the next field of the node

Institute of Lifelong Learning, University of Delhi 20


Queues

front 6 3 rear

addatrear (9) addatrear (5)

6 3 9 5

New link

front rear

deleteatfront()

rear
6

3 9 5
front
New link

Source:self
Fig 3.6 : Linked representation of Queue : enqueue and dequeue

3.3.4 Comparing Array and Linked implementations of Queue

When we compare the queue implementations, we look at two different factors: the
amount of memory required to store the structure and the amount of "work" required
by the solution, as expressed in Big-O notation. Let's compare the two implementations
that we have coded completely: the array-based implementation and the dynamically
linked implementation.

An array variable of the maximum queue size takes the same amount of memory, no
matter how many array slots are actually used; we need to reserve space for the

Institute of Lifelong Learning, University of Delhi 21


Queues

maximum possible number of elements. The linked implementation using dynamically


allocated storage space requires space only for the number of elements actually in the
queue at run time. Note, however, that the node elements are larger, because we must
store the link (the next member) as well as the user's data.

We can also compare the relative "efficiency" of the implementations, in terms of Big-O
notation. The class constructors, IsFull, and IsEmpty operations are clearly O(1); they
always take the same amount of work regardless of how many items are on the queue.
What about Enqueue and Dequeue? Does the number of elements in the queue affect
the amount of work done by these operations? No, it does not; in both implementations,
we can directly access the front and rear of the queue. The amount of work done by
these operations is independent of the queue size, so these operations also have O(1)
complexity.

Only the MakeEmpty operation differs from one implementation to the other. The static
array-based implementation merely sets the front and rear indexes, so it is clearly an
O(1) operation. The dynamic array-based implementation is only one statement, so it
also is O(1). The linked implementation must process every node in the queue to free
the node space. This operation, therefore, has O(N) complexity, where N is the number
of nodes in the queue. The class destructor was not needed in the statically allocated
array-based structure but was required in the dynamically allocated array-based
structure. The class destructor in the array-based implementation in dynamic storage
has only one statement, so it has O(1) complexity. The class destructor in the
dynamically allocated linked structure contains a loop that executes as many times as
there are items on the queue. Thus the dynamically linked version has O(N) complexity.
As with the array-based and linked implementations of stacks, these two queue
implementations are roughly equivalent in terms of the amount of work they do,
differing only in one of the six operations and in the class destructor. Table 5.3
summarizes the Big-O comparison of the queue operations.

Table 4.2 : Big-O Comparison of Queue Operations


Static Array Dynamic Array Linked
Implementation Implementation Implementation

Class O(1) O(1) O(1)


constructor

MakeEmpty O(1) O(1) O(N)

IsFull O(1) O(1) O(1)

IsEmpty O(1) O(1) O(1)

Enqueue O(1) O(1) O(1)

Dequeue O(1) O(1) O(1)

Destructor NA O(1) O(N)

Institute of Lifelong Learning, University of Delhi 22


Queues

Value addition: Pictorial representation


Circular Queue Enqueue Operation: An Illustration

Here , In Enqueue operation next rear position is calculated using modulus operator
implementing circular queue.

Source: www.cs.usfca.edu/~srollins/courses/cs112-f07/web/notes/queues.html

3.3.5 Generic Queue

When same queue can be used to hold different type of data is called Generic queue.
A C++ language construct that allows the compiler to generate multiple versions of a
class Queue type by allowing parameterized types. This is known as Generic queue.
This can be achieved using template parameters.

Template<class Queuetype>
class queue
{
Queuetype arr[MAX];
int front, rear;
public:
void enqueue(Queuetype);
Queuetype dequeue(void);
queue();
};
The main program code creates three different types of queue q1,q2,q3 where q1 is
integer queue, q2 is floating point queue, q3 is character queue using the following
statements:

Institute of Lifelong Learning, University of Delhi 23


Queues

queue<int> q1;
queue<float> q2;
queue<char> q3;

Similarly member functions can be made generic by using template keyword while
writing the description.

// Enqueue
template <class QueueType>
void queue<QueueType> :: enqueue(Queuetype)
{
……..........
}

//Dequeue
template <class QueueType>
QueueType queue<QueueType> :: dequeue(void)
{
……..........
}

//queue constructor
template <class QueueType>
queue<queueType> :: queue()
{
……..........
}

3.4 Circular Queue

3.4.1 Array Implementation

The need to move the elements in the array arose from our decision to keep the front
of the queue fixed in the first array slot. If we keep track of the index of the front as
well as the rear, we can let both ends of the queue float in the array.

Figure 3.8 shows how several Enqueue and Dequeue operations would affect the queue.
(For simplicity, the figure shows only the elements in the queue. The other slots
contain logical garbage, including dequeued values.) The Enqueue operations have the
same effect as before; they add elements to subsequent slots in the array and
increment the index of the rear indicator. The Dequeue operation is simpler, however.
Instead of moving elements up to the beginning of the array, it merely increments the
front indicator to the next slot. The MaxQue is the size of queue.

Institute of Lifelong Learning, University of Delhi 24


Queues

Enqueue(‘A’)

Front=0
A Rear =0

0 1 2 3 4
Enqueue(‘B’)

Front=0
A B Rear =1

0 1 2 3 4

Enqueue(‘C’)

A B C Front=0
Rear =2
0 1 2 3 4
Dequeue()

B C Front=1
Rear =2
0 1 2 3 4

Source:self
Figure 3.8: The effect of Enqueue and Dequeue

(a)Enqueue(‘L’)-Rear is at the bottom of the array

Front=3
J K Rear =4

0 1 2 3 4
(b)Using circular array, wrap the queue around to top of array

L J K Front=3
Rear =0
0 1 2 3 4

source: self
Figure 3.9: Wrapping the queue elements around

Institute of Lifelong Learning, University of Delhi 25


Queues

Letting the queue elements float in the array creates a new problem when the rear
indicator reaches the end of the array. In our first design, this situation told us that the
queue was full. Now, however, the rear of the queue might potentially reach the end of
the (physical) array when the (logical) queue is not yet full (Figure 3.9a).

Because space may still be available at the beginning of the array, the obvious solution
is to let the queue elements "wrap around" the end of the array. In other words, we
can treat the array as a circular structure, in which the last slot is followed by the first
slot (Figure 3.9b). To get the next position for the rear indicator, for instance, we can
use an if statement:

if (rear = = maxQue - 1)
rear = 0;
else
rear = rear + 1

We can also reset rear by using the remainder (%) operator:

rear = (rear + 1) % maxQue;


This solution leads us to a new problem: How do we know whether a queue is empty or
full? In Figure 3.10, we remove the last element, leaving the queue empty. In Figure
3.11, we add an element to the last free slot in the queue, leaving the queue full. The
values of front and rear, however, are identical in the two situations. We cannot
distinguish between a full queue and an empty queue.

(a)Initial conditions

Front=2
A Rear =2

0 1 2 3 4
(b)Dequeue()

Front=3
Rear =2
0 1 2 3 4

Source:self
Fig 3.10: An empty queue

Institute of Lifelong Learning, University of Delhi 26


Queues

(a)Initial conditions

Front=3
C D A B Rear =1

0 1 2 3 4
(b)Enqueue(‘E’)

C D E A B Front=3
Rear =2
0 1 2 3 4

Source:self Fig 3.11: A full queue

The first solution that comes to mind is to add another data member to our queue class,
in addition to front and rear-a count of the elements in the queue. When the count
member is 0, the queue is empty; when the count is equal to the maximum number of
array slots, the queue is full. Note that keeping this count adds work to the Enqueue
and Dequeue routines. If the queue user frequently needed to know the number of
elements in the queue, however, this solution would certainly be a good one. Another
common, but less intuitive approach is to let front indicate the index of the array slot
preceding the front element in the queue, rather than the index of the front element
itself. If rear still indicates the index of the rear element in the queue, the queue is
empty when front is equal to rear. To dequeue an element, we increment front to
indicate the true location of the front queue element, and assign the value in that array
slot to item. (Updating front precedes assigning the value in this design, because front
does not point to the actual front element at the beginning of Dequeue.) After this
Dequeue operation, IsEmpty finds that front is equal to rear, indicating that the queue
is empty (see Figure 3.12).

(a)Initial conditions

Front=1
A Rear =2

0 1 2 3 4
(b)Dequeue()

Front=2
Rear =2
0 1 2 3 4

Institute of Lifelong Learning, University of Delhi 27


Queues

Figure 3.12: Testing for an empty queue


Source:self

An additional convention that we must establish to implement this scheme is that the
slot indicated by front (the slot preceding the true front element) is reserved. It cannot
contain a queue element. Thus, if there are 100 array positions, the maximum size of
the queue is 99 elements. To test for a full queue, we check whether the next space
available (after rear) is the special reserved slot indicated by front (see Figure 3.13).

C D reserved A B Front=2
Rear =1
0 1 2 3 4

Fig 3.13: Testing for a full queue


Source:self

To enqueue an element, we must first increment rear so that it contains the index of
the next free slot in the array. We can then insert the new element into this space.

Using this scheme, how do we initialize a queue to its empty state? We want front to
indicate the array index that precedes the front of the queue, so that when we first call
Enqueue the front of the queue is in the first slot of the array. Which position precedes
the first array slot? Because the array is circular, the first slot is preceded by the last
slot. As a consequence, we initialize front to maxQue - 1. Because our test for an
empty queue is checking whether front is equal to rear, we initialize rear to front, or
maxQue - 1.

Now we see that we must add two data members to the QueType class: front and rear.
The header file follows. Through the parameterized constructor, we let the user
determine the maximum size of the queue when a class object is declared. Because our
implementation takes one more array slot, we must increment max (the parameter to
the constructor) before we save it in maxQue. (This implementation is called a circular
or ring queue.) The modified version of circular queue code is given below:

class FullQueue
{}:
class EmptyQueue
{};

typedef char ItemType;


class QueType
{
public:
QueType(int max);
QueType();
~QueType();
void MakeEmpty();

Institute of Lifelong Learning, University of Delhi 28


Queues

bool IsEmpty() const;


bool IsFull() const:
void Enqueue(ItemType newItem);
void Dequeue(ItemType& item);
private:
int front;
int rear;
ItemType* items;
int maxQue;
};
QueType::QueType(int max)
// Parameterized class constructor.
// Post: maxQue, front, and rear have been initialized.
// The array to hold the queue elements has been dynamically
// allocated.
{
maxQue = max + 1;
front = maxQue - 1;
rear = maxQue - 1;
items = new ItemType[maxQue];
}
QueType::QueType() // Default class constructor.
// Post: maxQue, front, and rear have been initialized.
// The array to hold the queue elements has been dynamically
// allocated.
{
maxQue = 501;
front = maxQue - 1;
rear = maxQue - 1;
items = new ItemType[maxQue];
}
QueType::~QueType() // Class destructor.
{
delete [] items;
}
void QueType::MakeEmpty()
// Post: front and rear have been reset to the empty state.
{
front = maxQue - 1;
rear = maxQue - 1;
}
bool QueType::IsEmpty() const
// Returns true if the queue is empty; false otherwise.
{
return (rear == front);
}
bool QueType::IsFull() const
// Returns true if the queue is full; false otherwise.
{
return ((rear + 1) % maxQue == front);
}

Institute of Lifelong Learning, University of Delhi 29


Queues

void QueType::Enqueue(ItemType newItem)


// Post: If (queue is not full) newItem is at the rear of the queue;
// otherwise, a FullQueue exception is thrown.
{
if (IsFull())
throw FullQueue();
else
{
rear = (rear +1) % maxQue;
items[rear] = newItem;
}
}
void QueType::Dequeue(ItemType& item)
// Post: If (queue is not empty) the front of the queue has been
// removed and a copy returned in item;
// otherwise, an EmptyQueue exception is thrown.
{
if (IsEmpty())
throw EmptyQueue();
else
{
front = (front + 1) % maxQue;
item = items[front] ;
}
}

Institute of Lifelong Learning, University of Delhi 30


Queues

Fig 3.14: Queue in circular array


Source: Data Structures and Program Design in C++ - Robert L. Kruse

Note that Dequeue, like the stack Pop operation, does not actually remove the value of
the item from the array. The dequeued value still physically exists in the array. It no
longer exists in the queue, however, and cannot be accessed because of the change in
front. That is, the dequeued data element exists in the implementation but not in the
abstraction.

Comparing Array Implementations The circular array solution is not nearly as simple or
intuitive as first queue design. What did we gain by adding some amount of complexity
to our design? By using a more efficient Dequeue algorithm, we achieved better
performance. To find out how much better, analyzing the first design. Because the
amount of work needed to move all of the remaining elements is proportional to the
number of elements, this version of Dequeue is an 0(N) operation. The second array-
based queue design simply requires Dequeue to change the values of the front
indicator and to put the value into item to be returned. The amount of work never
exceeds some fixed constant, no matter how many elements are in the queue, so the
algorithm has 0(1) complexity.

The other operations all have 0(1) complexity. No matter how many items are in the
queue, they do (essentially) a constant amount of work.

3.4.2 Linked Implementation

Our QueType class contains two pointers, one to each end of the queue. This design is
based on the linear structure of the linked queue. Given only a pointer to the front of
the queue, we could follow the pointers to reach the rear, but this tactic turns
accessing the rear (to Enqueue an item) into an O(N) operation. With a pointer to the
rear of the queue only, we could not access the front because the pointers go only from
front to rear.

If we made the queue circularly linked, we could access both ends of the queue from a
single pointer. That is, the next member of the rear node would point to the front node
of the queue (see Figure 3.15). Now QueType has only one data member, rather than
two. One interesting thing about this queue implementation is that it differs from the
logical picture of a queue as a linear structure with two ends. This queue is a circular
structure with no ends. What makes it a queue is its support of FIFO access.

Institute of Lifelong Learning, University of Delhi 31


Queues

Front of a Rear of a queue


queue

rear

Fig 3.15 : A circular Linked Queue

Source:self

To Enqueue an element, we access the "rear" node directly through the pointer rear. To
Dequeue an element, we access the "front" node of the queue. We don't have a pointer
to this node, but we do have a pointer to the node preceding it-rear. The pointer to the
"front" node of the queue is in Next(rear). An empty queue is represented by rear =
NULL.We can test both linked implementations of the Queue ADT by using the same
test plan that we wrote for the array-based version.

3.5 DeQue
A double-ended queue is an abstract data type similar to an ordinary queue, except
that it allows you to insert and delete from both sides. The term deque is a contraction
of the name double-ended queue. There are two variations of a deque,
These are :-

1.Input restricted deque- which allows insertion only at one end and allows deletions
at both ends.
2.Output restricted deque-which allow insertions at both ends but allow deletions
only at one end.

It supports the following operations: add_at_front, add_at_back, delete_at_front,


delete_at_back, and empty. By choosing a subset of deque operations, we can make
the double-ended queue behave like a stack or like a queue. For instance, if we use
only add_at_front and delete_at_front we get a stack, and if we use only add_at_front
and delete_at_back we get a queue.

Institute of Lifelong Learning, University of Delhi 32


Queues

addatfront addatback
e

Deleteatfront 0 1 2 3 4
Deleteatback

Fig 3.16 : Representing Double Ended Queue


Source:self
Double Ended queue can be implemented using array, Singly linked list or doubly
Linked List. Here ,we are writing class structures and some functions for Menu driven
Deque using doubly linked list. We can write the separate functions for all operations of
deque.

//description of doubly linked list node


class node
{
public:
int data;
node *next;
node *prev;
};

//description of double ended queue having two pointers head and tail
class dqueue: public node
{
node *head,*tail;

public:
dqueue()
{
head=NULL;
tail=NULL;
}
};
// the insertion into doubly ended Queue at front and back
void insert(int x){
node *temp;
int ch;

if( head == 0)
{// add first data at head if queue empty
head = new node;
head->data=x;
head->next=NULL;
head->prev=NULL;
tail=head;

Institute of Lifelong Learning, University of Delhi 33


Queues

else
{
cout <<" Add element 1.FRONT 2.BACK\n enter ur choice:";
cin >> ch;

if(ch==1)
{// add at front
temp=new node;
temp->data=x;
temp->next=head;
temp->prev=NULL;
head->prev=temp;
head=temp;
}
else
{// add at back
temp=new node;
temp->data=x;
temp->next=NULL;
temp->prev=tail;
tail->next=temp;
tail=temp;
}

}
};

//deletion from double ended queue from front and back


void delete()
{
int ch;
cout <<"Delete 1.Front Node 2. Back Node\n Enter ur choice:";
cin >>ch;

if(ch==1)
{
//deletes at front
head=head->next;
head->prev=NULL;
}
Else
{
// delete at back
tail=tail->prev;
tail->next=NULL;
}
};

Institute of Lifelong Learning, University of Delhi 34


Queues

// display of double ended queue from front and back


void display()
{
int ch;
node *temp;
cout <<"display from 1.Staring 2.Ending\n Enter ur choice";
cin >>ch;
if (ch==1)
{
temp=head;
while(temp!=NULL)
{
cout << temp->data <<" ";
temp=temp->next;
}
}
else
{
temp=tail;
while( temp!=NULL)
{
cout <<temp->data << " ";
temp=temp->prev;
}
}
};

// main program calling functions


main()
{
dqueue d1;
int ch;
while (1){
cout <<"1.Insert 2.Delete 3.Display 4.Exit\n Enter ur choice:";
cin >>ch;
switch(ch)
{
case 1: cout <<"enter element";
cin >> ch;
d1.insert(ch); break;
case 2: d1.delete(); break;
case 3: d1.display(); break;
case 4: exit(1);
}
}}

Institute of Lifelong Learning, University of Delhi 35


Queues

(1)Original List

head 6 3 tail

(2) addatback (9) addatback(5)

6 3 9 5

New link

head tail

(3) deleteatfront()

tail
6

3 9 5
head
New link

(4) Addatfront(7)
New link tail
7 New link

New link
3 9 5
head

(5) deleteatback()

7 3 9 5

New link

head tail

Institute of Lifelong Learning, University of Delhi 36


Queues

Fig 3.17: Illustrating Dequeue using Doubly Linked List


Source:self

3.5 Priority Queue

Fig 3.18: Priority Queue


Source: www.cisco.com/en/US/products/hw/switches/ps70

A priority queue is an abstract data type (ADT) which have elements arranged in the
list according to their priority. It supporting the following three main operations:

1. Add an element to the queue with an associated priority


2. Remove the element from the queue that has the highest priority, and return it
3. peek at the element with highest priority without removing it

The priority queue can do number of operations insertion and deletion of element,
finding element with maximum priority of minimum priority, searching an element
according to priority. The priority queue can implemented using array, singly linked list,
doubly linked list . Here, we are using doubly linked list for implementation . assuming
that data stored into the node is priority itself. We can have different structures of node
as having data as well as priority stored in it or having data such that it is a priority
itself. The following code contain some member functions as well as class structure in
detail required to implement priority queue.

Institute of Lifelong Learning, University of Delhi 37


Queues

The class required for the priority queue are Node and Priorityqueue for
node of doubly linked list and priority queue itself conataining member
functions.

Class Node // Node of Priority Queue( doubly linked list)


{
Node *Previous;
int Data;
Node *Next;
};

class PriorityQueue // Class Prioriry Queue


{
private:
Node *head; // Pointer to Head

public:
PriorityQueue();
int Maximum(void);
int Minimum(void);
void Insert(int);
int Delete(int);
void Display(void);
int Search (int);
~PriorityQueue(void);
};
constructor can be written as:

// Constructor
PriorityQueue::PriorityQueue()
{
head=0;

Some of the functions are given for a reference. Others can be wriiten
similarly to complete the program.
// Function Finding Maximum Priority Element
int PriorityQueue::Maximum(void)
{
Node *ptr;
int Temp;
ptr=head;
Temp=ptr->Data;

while(ptr->Next!=NULL)
{
if(ptr->Data>Temp)
Temp=ptr->Data;
ptr=ptr->Next;
}
if(ptr->Next==NULL && ptr->Data>Temp)
Temp=ptr->Data;

Institute of Lifelong Learning, University of Delhi 38


Queues

return(Temp);
}

// Function inserting element in Priority Queue


void PriorityQueue::Insert(int DT)
{
Node *newnode, *ptr;
newnode=new Node();
newnode->Data=DT;
while(ptr->Next!=NULL)
ptr=ptr->Next;
if(ptr->Next==NULL)
{
newnode->Next=ptr->Next;
ptr->Next=newnode;
}

// Function deleting element in Priority Queue


int PriorityQueue::Delete(int DataDel)
{
Node *mynode,*temp,*ptr;

ptr=head;

if(head==0)
{
cout<<"Cannot Delete the only Node"<<endl;
return 0;
}
if(ptr->Data==DataDel)
{

/*** Checking condition for deletion of first node ***/


temp=ptr;
ptr=ptr->Next;
ptr->Previous=NULL;
delete temp;
head=ptr;
return(1);
}
else
{
while(ptr->Next->Next!=NULL)

{
/*** Checking condition for deletion of ***/
/*** all nodes except first and last node ***/
if(ptr->Next->Data==DataDel)

Institute of Lifelong Learning, University of Delhi 39


Queues

mynode=ptr;
temp=ptr->Next;
mynode->Next=mynode->Next->Next;
mynode->Next->Previous=ptr;
delete temp;
return(1);
}
ptr=ptr->Next;
}
if(ptr->Next->Next==NULL && ptr->Next->Data==DataDel)
{
/*** Checking condition for deletion of last node ***/
temp=ptr->Next;
delete temp;
ptr->Next=NULL;
return(1);
}
}
return(0);
}
// Function Searching element in Priority Queue
int PriorityQueue::Search(int DataSearch)
{
Node *ptr;
ptr=head;

while(ptr->Next!=NULL)
{
if(ptr->Data==DataSearch)
return ptr->Data;
ptr=ptr->Next;
}
if(ptr->Next==NULL && ptr->Data==DataSearch)
return ptr->Data;
return(0);
}

// Destructor of Priority Queue


PriorityQueue::~PriorityQueue(void)
{
Node *temp; /* Temporary variable */
while(head->Next!=NULL)
{
temp=head->Next;
// delete head;
head=temp;
}

if(head->Next==NULL)
delete head;

Institute of Lifelong Learning, University of Delhi 40


Queues

}
//Main Function
void main()
{
PriorityQueue PQ;
int choice;
int DT;

while(1)
{
cout<<"Enter your choice"<<endl;
cout<<"1. Insert an element"<<endl;
cout<<"2. Display a priorty Queue"<<endl;
cout<<"3. Delete an element"<<endl;
cout<<"4. Search an element"<<endl;
cout<<"5. Exit"<<endl;
cin>>choice;
switch(choice)
{
case 1:
cout<<"Enter a Data to enter Queue"<<endl;
cin>>DT;
PQ.Insert(DT);
break;
case 2:
PQ.Display();
break;
case 3:
{
int choice;
cout<<"Enter your choice"<<endl;
cout<<"1. Maximum Priority Queue"<<endl;
cout<<"2. Minimum Priority Queue"<<endl;
cin>>choice;
switch(choice)
{
case 1:
PQ.Delete(PQ.Maximum());
break;
case 2:
PQ.Delete(PQ.Minimum());

break;
default:
cout<<"Sorry Not a correct choice"<<endl;
}
}
break;

case 4:
cout<<"Enter a Data to Search in Queue"<<endl;
cin>>DT;

Institute of Lifelong Learning, University of Delhi 41


Queues

if(PQ.Search(DT)!=FALSE)
cout<<DT<<" Is present in Queue"<<endl;

else
cout<<DT<<" is Not present in Queue"<<endl;
break;

case 5:
exit(0);
default:
cout<<"Cannot process your choice"<<endl;
}
}
}

Fig 3.19: Priority Queue operations

Source: www.coopsoft.com/ar/PriQueArticle.html

Institute of Lifelong Learning, University of Delhi 42


Queues

Value addition: Do you Know


How Priority Queue is implemented using standard template
library?

Institute of Lifelong Learning, University of Delhi 43


Queues

Source: Data Structure And Algorithms In C++ 2nd ed - Adam Drozdek

5 Queue: Applications

5.1 Queue as scheduling queue

A queue is natural data structure for a system to serve the incoming requests. Most of the
process scheduling or disk scheduling algorithms in operating systems use queues.
We can implement a round robin scheduler using a queue, Q, by repeatedly performing
the following steps:
1. e = Q.dequeue()
2. Service element e
3. Q.enqueue(e)

The Queue

1. Deque the 2. Service the 3. Enqueue the


next serviced
element element
Shared
Service

Institute of Lifelong Learning, University of Delhi 44


Queues

fig 3.20: Round Robin Schedular


source:www.ics.uci.edu/~stasio/winter06/Lectures/GTlectures/lec6.ppt

Fig 3.21: Job Scheduling


http://msdn.microsoft.com/en-us/library/bb524833(VS.85).aspx

Value addition: Do you Know


What is Multiple level priority queue scheduling?

While working with the operation system, it access many jobs. Jobs are added into a queue known as
Job queue. One by One Job is retrieved from the job queue and added to the ready queue for assigning
it to processor. This generates the ready queue. Now, This algorithm partitions the ready queue into
several separate queues. The nature of jobs in this multilevel queue is different . According to the
nature , the queue is given priority for executing jobs in it. These jobs are in the form of processes.
There can be many types of processes queue like system queue contains all system processes. The
processes are permanently assigned to one queue based on some property of the process. Each queue
has its own specific scheduling algorithm. Consider the following illustration of Multilevel priority
queue scheduling:

Institute of Lifelong Learning, University of Delhi 45


Queues

Each queue has absolute priority over lower priority queues. No process in batch queue will be able to
run until the queues above it are empty. Another possibility is to time slice between the queues by
allotting each process with a certain portion of CPU time.

Multilevel Feedback Queue Scheduling


Here, processes are not permanently assigned to a queue on entry to the system. Instead, they are
allowed to move between queues. The idea is to separate processes with different CPU burst
characteristics. If a process uses too much CPU time, it will be moved to a lower priority queue.
Similarly, a process that waits too long in a low priority queue will be moved to a higher priority
queue. This form of aging prevents starvation.

Institute of Lifelong Learning, University of Delhi 46


Queues

Source:http://read.cs.ucla.edu/111/notes/lec7

5.2 Queue as Buffering queue

Computer hardware like processor or a network card also maintain buffers in the form
of queues for incoming resource requests. A stack like data structure causes starvation
of the first requests, and is not applicable in such cases. A mailbox or port to save
messages to communicate between two users or processes in a system is essentially a
queue like structure. To be specific ,A circular queue buffer is used for storage of data
in various activities of computers. This buffer is known as cyclic buffer or ring buffer. It
is a data structure that uses a single, fixed-size buffer as if it were connected end-to-
end. This structure lends itself easily to buffering data streams.

An example that could possibly use an overwriting circular buffer is with multimedia. If
the buffer is used as the bounded buffer in the producer-consumer problem then it is
probably desired for the producer (e.g., an audio generator) to overwrite old data if the
consumer (e.g., the sound card) is unable to momentarily keep up. Another example is
the digital waveguide synthesis method which uses circular buffers to efficiently
simulate the sound of vibrating strings or wind instruments.

Institute of Lifelong Learning, University of Delhi 47


Queues

The "prized" attribute of a circular buffer is that it does not need to have its elements
shuffled around when one is consumed. (If a non-circular buffer were used then it
would be necessary to shift all elements when one is consumed.) In other words, the
circular buffer is well suited as a FIFO buffer while a standard, non-circular buffer is
well suited as a LIFO buffer.

Fig 3.22:Circular Queue Buffer


Source:Wikipedia

It is a ring like structure having one pointer to access the element . It act as a buffer to
store data so that there is no wastage of the locations in the queue. It insert and delete
the elements in sequence . After the queue reaches the maximum , it again starts
from first location and act as a continuous buffer for storing data.

5.3 Queue–Search space exploration

Like stacks, queues can be used to remember the search space that needs to be explored at
one point of time in traversing algorithms. Breadth first search of a tree uses a queue to
remember the nodes yet to be visited. It is a level by level traverse in a graph or a tree. The
following tree BFS traversal gives the sequence 1 2 3 4 5 6 7 8 9 10 11 12 after traversing
the nodes level by level. For coding this traversal we require a Queue as under:

Institute of Lifelong Learning, University of Delhi 48


Queues

Value addition: Frequently asked Question


How Queue is used for implementation of BFS search?

Algorithm-BFS

1. Enqueue the root node.


2. Dequeue a node
3. visit the node.
4. If the node has child nodes,enqueue the child node in the
Queue .
5. If the queue is empty, every node on the tree has been visited
and return. Otherwise,
6. If queue is not empty,Repeat from Step 2.

Here , Traversing starts from root node. Visiting this parent node requires to
store its child node which are at next level. Queue is used to store the child
nodes of this currently visited node. The next node is then dequeued from the
queue to be visited and again stores it children in the Queue. This process
should go on till the queue is empty. The sequence of visit gives the Breadth
first traversal of tree.

Fig 3.23: Breadth first search in a Tree


Source: http://upload.wikimedia.org/wikipedia/commons/b/bc/Breadth-first-tree.png

Institute of Lifelong Learning, University of Delhi 49


Queues

5.4 Circular queue in real life

Traffic light sequence on a large roundabout is an example of circular queue. It changes the
signals circularly in a sequence with equal interval of time. Some other real time examples
are print spooler of operating system,bottle caping systems in cold drink factory,
resolves bullet cylinder when place an object into two side opened container and biscuit
baking.

Fig 3.23 Bottle caping system in a circular queue.

Source: http://i.ytimg.com/vi/GELrKh8lrRw/0.jpg

5.5 Applications of Priority Queue

Bandwidth management

Priority queuing can be used to manage limited resources such as bandwidth on a


transmission line from a network router. In the event of outgoing traffic queuing due to
insufficient bandwidth, all other queues can be halted to send the traffic from the
highest priority queue upon arrival. This ensures that the prioritized traffic (such as
real-time traffic, e.g. an RTP stream of a VoIP connection) is forwarded with the least
delay and the least likelihood of being rejected due to a queue reaching its maximum
capacity. All other traffic can be handled when the highest priority queue is empty.
Another approach used is to send disproportionately more traffic from higher priority
queues.

Institute of Lifelong Learning, University of Delhi 50


Queues

Many modern protocols for Local Area Networks also include the concept of Priority
Queues at the Media Access Control (MAC) sub-layer to ensure that high-priority
applications (such as VoIP or IPTV) experience lower latency than other applications
which can be served with Best effort service. Examples include IEEE 802.11e (an
amendment to IEEE 802.11 which provides Quality of Service) and ITU-T G.hn (a
standard for high-speed Local area network using existing home wiring (power lines,
phone lines and coaxial cables).

Usually a limitation (policer) is set to limit the bandwidth that traffic from the highest
priority queue can take, in order to prevent high priority packets from choking off all
other traffic. This limit is usually never reached due to high level control instances such
as the Cisco Callmanager, which can be programmed to inhibit calls which would
exceed the programmed bandwidth limit.

Discrete event simulation

Another use of a priority queue is to manage the events in a discrete event simulation.
The events are added to the queue with their simulation time used as the priority. The
execution of the simulation proceeds by repeatedly pulling the top of the queue and
executing the event thereon.

Dijkstra's algorithm

When the graph is stored in the form of adjacency list or matrix, priority queue can be
used to extract minimum efficiently when implementing Dijkstra's algorithm.

A* and SMA* search algorithms

The A* search algorithm finds the shortest path between two vertices of a weighted
graph, trying out the most promising routes first. The priority queue (also known as the
fringe) is used to keep track of unexplored routes; the one for which a lower bound on
the total path length is smallest is given highest priority. If memory limitations make
A* impractical, the SMA* algorithm can be used instead, with a double-ended priority
queue to allow removal of low-priority items.

ROAM triangulation algorithm

The Real-time Optimally Adapting Meshes (ROAM) algorithm computes a dynamically


changing triangulation of a terrain. It works by splitting triangles where more detail is
needed and merging them where less detail is needed. The algorithm assigns each
triangle in the terrain a priority, usually related to the error decrease if that triangle
would be split. The algorithm uses two priority queues, one for triangles that can be
split and another for triangles that can be merged. In each step the triangle from the
split queue with the highest priority is split, or the triangle from the merge queue with
the lowest priority is merged with its nieghbours.

Relationship to sorting algorithms

The semantics of priority queues naturally suggest a sorting method: insert all the
elements to be sorted into a priority queue, and sequentially remove them; they will

Institute of Lifelong Learning, University of Delhi 51


Queues

come out in sorted order. This is actually the procedure used by several sorting
algorithms, once the layer of abstraction provided by the priority queue is removed.
This sorting method is equivalent to the following sorting algorithms:

 Heapsort if the priority queue is implemented with a heap.


 Selection sort if the priority queue is implemented with an ordered
array.
 Insertion sort if the priority queue is implemented with an unordered
array.

A sorting algorithm can also be used to implement a priority queue.

5.6 Queue as Message queue


In computer science, message queues and mailboxes are software-engineering
components used for interprocess communication, or for inter-thread communication
within the same process. They use a queue for messaging – the passing of control or of
content. Group communication systems provide similar kinds of functionality.

Message queues provide an asynchronous communications protocol, meaning that the


sender and receiver of the message do not need to interact with the message queue at
the same time. Messages placed onto the queue are stored until the recipient retrieves
them.

Many implementations of message queues function internally: within an operating


system or within an application. Such queues exist for the purposes of that system
only.Other implementations allow the passing of messages between different computer
systems, potentially connecting multiple applications and multiple operating systems.

Value addition: Do you Know


What is Microsoft Message Queue(MSMQ)?

Microsoft Message Queuing or MSMQ is a Message Queue implementation


developed by Microsoft and deployed in its Windows Server operating systems
since Windows NT 4 and Windows 95. The latest Windows 7 also include this
component. In addition to its mainstream server platform support, MSMQ has
been incorporated into Microsoft Embedded platforms since 1999 and the release
of Windows CE 3.0.

MSMQ is essentially a messaging protocol that allows applications running


on separate servers/processes to communicate in a failsafe manner. A queue is a
temporary storage location from which messages can be sent when conditions permit.
This enables communication across heterogeneous networks and between computers
which may not always be connected. By contrast, sockets and other network protocols
assume that direct connections always exist.

Institute of Lifelong Learning, University of Delhi 52


Queues

Fig 3.25: Message Queue


www.ibm.com/.../0511_ma/0511_ma.html

Institute of Lifelong Learning, University of Delhi 53


Queues

Value addition: Pictorial representation


Message Queue Operation: An Illustration

Applications communicate over networks by simply putting messages in queues and getting
messages from queues.

Source: http://middlewares.files.wordpress.com/2008/04/19.jpg

Institute of Lifelong Learning, University of Delhi 54


Queues

Value addition: Pictorial representation

Multiple message through one queue controlling many client


server Machines: An Illustration

 any clients are sending requests to one server queue.


 The messages are picked off the queue by multiple instances of the server program
that are concurrently servicing the clients.

Source: http://middlewares.files.wordpress.com/2008/04/21.jpg

Institute of Lifelong Learning, University of Delhi 55


Queues

5.7 The M/M/1 Queue

The Markov/Markov/Single-Server model is a fundamental queueing model in


operations research and probability theory. Tasks arrive according to a Poisson process
at a certain rate λ. This means that λ customers arrive per hour. More specifically, the
arrivals follow an exponential distribution with mean 1 / λ: the probability of k arrivals
between time 0 and t is (λ t)^k e^(-λ t) / k!. Tasks are serviced in FIFO order
according to a Poisson process with rate μ. The two M's standard for Markov: it means
that the system is memoryless: the time between arrivals is independent, and the time
between departures is independent.

Value addition: Other works

Efficient data structures for Time Warp simulation queues

Optimistic simulation is besides the conservative methods the most promising approach
to distributed discrete-event simulation (DDEVS). In the optimistic Time Warp strategy,
every sub-simulator has to handle in addition to its main event queue (input queue)
two other queues, holding information about sent messages and past states,
respectively. We present efficient data structures and algorithms for the three queue
types in Time Warp simulation. It shows that for two queue types the simple doubly
linked list (DLL) approach suffices, for the input queue however, significant speed-up
can be achieved by enhancing a data structure originally developed for sequential
simulation. We show an improvement from an O(n) to an O(1) average case behavior
for some operations by moving from the DLL to the new data structure without
increasing the average case and worst case order of the other operations. Empirical
results show that the new data structure yields substantial faster operation for
enqueuing items into the list, which — regardless of the overhead introduced by the
new data structure to the other queue operations — results in queue access
acceleration for typical Time Warp simulations even for medium input queue sizes of
about 100. For large queue sizes of about 10000 the new data structure yields more
than 15 times faster overall queue operation performance.

Institute of Lifelong Learning, University of Delhi 56


Queues

Value addition: Do you Know


How is Queue used in implemented using standard template
library?

Source Data Structure And Algorithms In C++ 2nd ed - Adam Drozdek

Institute of Lifelong Learning, University of Delhi 57


Queues

Value addition: Do you Know


How is Deque implemented using standard template library?

Institute of Lifelong Learning, University of Delhi 58


Queues

Institute of Lifelong Learning, University of Delhi 59


Queues

Institute of Lifelong Learning, University of Delhi 60


Queues

Source: Data Structure And Algorithms In C++ 2nd ed - Adam Drozdek

Summary

 Queue is an abstract data structure which has two ends front and rear for
inserting and deleting an element.
 It works on a principle of first in first out. Its main operations are enqueue and
dequeue for inserting and deleting an element respectively from the Queue.
 Insertion takes place from the rear and deletion is allowed from the front.It
moves two pointers to reflect the status of Queue at that moment.
 Queue is implemented mainly in two representations : Array and Linked. Array
implementation is static in nature but Linked representation involves dynamic
nature of queue to grow.
 Queue can be represented using two stacks with the help of simulation of FIFO
principle with LIFO.
 Circular Queue is the queue which is continuous in storage not wasting the
empty locations of the queue.
 Another form of queue is priority queue which stores the element depending
upon their priority attached to it. This queue has many application in the
different areas of managing computers.
 Similarly, Deque is double ended Queue which allow insertion and deletion from
both ends.
 Queue has many applications like job scheduling, breadth first traversal,
message communication ,sorting techniques, simulation etc.

Exercises

Q.1 Design a complete code for all the functions of the Queue?

Q.2 Write the code for solving polynomial Addition using Queue?

Q. 3. Implement Linked Queue Using Singly linked list and Doubly Linked List.

Institute of Lifelong Learning, University of Delhi 61


Queues

Q.4 Write the following functions using Queue ADT


a) Copy content from one queue to another in same order.
b) Copy content from one queue to another in reverse order.

Q.5 Implement circular queue using Doubly linked list.

Q.6 List some of the real life examples where you can use the priority Queue.

Q.7 Write the following functions using Queue


a) check whether two queues are identical
b) replace all occurrences of element with the new element.
c) count the number of elements in Queue.

Creative Exercises

1. Deque A double-ended queue or deque (pronounced deck) is a combination of a


stack and and a queue. It stores a parameterized collection of items and
supports the following API:

Write a data type Deque.cpp that implements the deque using a singly linked
list.

2. Random queue. Create an abstract data type RandomizedQueue.cppthat


supports the following operations: isEmpty(), insert(), random(), and
removeRandom(), where the deletion operation deletes and returns a random
object. Hint: maintain an array of objects. To delete an object, swap a random
object (indexed 0 through N-1) with the last object (index N-1). Then, delete
and return the last object.

Institute of Lifelong Learning, University of Delhi 62


Queues

Glossary

Abstract data type

A data type whose properties (domain and operations) are specified


independently of any particular representation : a class of data objects with a
defined set of operations that process the data objects while maintaining its
properties.

Algorithm

A logical sequence of discrete steps that describes a complete solution to a


given problem.

Big-O notation

A notation that expresses computing time (complexity) as the term in a


function that increases most rapidly relative to the size of the problem.

Circular Linked List

A list in which every node has a successor; but last element is succeded by
first element.

Constructor

An operation that builds new instances of an abstract data type .

Delimiter

A symbol or keyword that marls the beginning or end of the construct.

Institute of Lifelong Learning, University of Delhi 63


Queues

DeQue

Double Ended Queue is the queue in which insertion and deletion is done at
both ends.

Doubly Linked list

A linked list in which each node is linked to both its successor and its
predecessor.

Dynamic data structure

A data structure that can expand and contract during program execution.

Implementing

Coding and testing an algorithms

Index

A value that selects the component from the array.

Priority Queue

Priority queue is a type of queue in which each element is having a priority


attach to it.

Queue

A queue is a particular kind of collection in which the entities in the collection


are kept in order and the principal (or only) operations on the collection are
the addition of entities to the rear terminal position and removal of entities
from the front terminal position. This makes the queue a First-In-First-Out
(FIFO) data structure.

References

Suggested Readings

1. Fundamentals of Data Structures - Ellis Horowitz

Institute of Lifelong Learning, University of Delhi 64


Queues

2. Data Structure And Algorithms In C++ 2nd ed - Adam Drozdek

3. Algorithms and Data Structures in CPlusPlus - Alan Parker

4. C++ plus Data Structures 4th ed - Nell Dale

5. Data Structures and Algorithms - Alfred V. Aho

6. Data Structures and Program Design in C++ - Robert L. Kruse

7. Data Structure using C and C++ - Langsam ,Augenstein and Tanenebaum

Web Links

1. www.codefords.wordpress.com

2. www.Wikipedia .org

3. www. read.cs.ucla.edu

4. www.cs.usfca.edu

Institute of Lifelong Learning, University of Delhi 65

You might also like