Queues
Maria Sabir
Introduction to Queues
 The queue data structure is very similar to the stack.
 In a stack, all insertions and deletions occur at one
end, the top, of the list.
 In the queue, as in the stack, all deletions occur at the
head (front) of the list.
 However, all insertions to the queue occur at the tail
(back or rear) of the list.
Introduction to Queues
 Basically, data enters the queue at one end and exits
at the other end.
 This characteristic gives a queue its first-in, first-out
(FIFO) behavior.
ADT Queue
Collection of Data Elements:
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 rear (end) of the queue
Basic Operations:
1. MAKENULL(Q): Makes Queue Q be an empty list.
2. FRONT(Q): Returns the first element on Queue Q.
3. ENQUEUE(x,Q): Inserts element x at the rear (end) of Queue Q.
4. DEQUEUE(Q): Deletes the first element of Q.
5. EMPTY(Q): Returns true if and only if Q is an empty queue.
Implementation
 Static
Queue is implemented by an array, and size of
queue remains fix
 Dynamic
A queue can be implemented as a linked list, and
expand or shrink with each enqueue or dequeue
operation.
Enqueue
 The queue insert is known as enqueue.
 After the data has been inserted, this new element
becomes the rear of the queue.
Dequeue
 The queue delete operation is known as dequeue.
 The data at the front of the queue is returned to the
user and deleted from the queue.
Queue Front
 Data at the front of the queue can be examined with
queue front.
 This function returns the data at the front of the queue
but does not remove it from the queue.
Queue Rear
 Similar to queue front is queue rear.
 This function examines the data stored in the rear
element of the queue, but does not remove it.
Queue Example
Queue Example
Linked List Implementation
 Several data structures could be used to implement a
queue (including an array).
 However, we will discuss a linked list implementation
first.
 As with any linked list, we have 2 structures:
List
Node
Linked List Implementation
 The List structure contains the metadata (e.g., number
of elements in the queue) and pointers to the front and
rear elements of the queue.
 The Node structure contains the data and a pointer to
the next element in the queue.
m.alishahid
Linked List Implementation
Queue Algorithms
 We now develop the pseudocode to implement some
basic operations that can be performed on a queue.
 Then, we will discuss an actual C++ implementation.
Create Queue
 This function initializes the metadata for the queue structure.
? ?
count front
queue
0 count = 0
Pseudocode
front = NULL
rear = NULL
rear
? 0
0
Enqueue
 This function inserts an element into the queue.
 We need to:
Allocate memory for the new node.
Update the link field of the rear node to point to the
new rear (the inserted element).
Update the rear pointer to point to the new rear
element of the queue.
Increment the count of nodes in the queue.
Enqueue
Pseudocode
rear->link = pNew
queue
rear = pNew
Here, we want to insert our new
node into the queue.
count front
0
75
pNew
1
39
2
0
rear
Enqueue Pseudocode
if( count is zero )
front = pNew
else
rear->next = pNew
end if
rear = pNew
count++
Dequeue
 This function removes an element from the
queue.
 We need to:
Return the data at the front of the queue.
Recycle the memory from the front node.
Update the front pointer to point to the new
front of the queue.
Decrement the count of nodes in the queue.
Dequeue
Pseudocode
dltPtr = front
3
count front
queue
134
39
Here, we want to remove the
first node in the queue (39).
75
0
dltPtr
delete dltPtr
(available)
2
dataOut = front->data
front = front->link
0
dataOut
rear
Dequeue Pseudocode
if( queue not empty )
dltPtr = front
dataOut = front->data
front = front->link
delete dltPtr
count--
if( count == 0)
rear = NULL
end if
end if
Queue Front
 This function returns the data from the front of the
queue, but does not remove the node from the
queue.
if (queue empty)
success = false
else
dataOut = front->data
success = true
end if
return success
Queue Rear
 This function returns the data from the rear of the
queue, but does not remove the node from the
queue.
if (queue empty)
success = false
else
dataOut = rear->data
success = true
end if
return success
IsEmpty Queue
 This function checks to see if the queue is empty.
if (queue empty)
return true
else
return false
end if
Queue Count
 This function returns the number of elements
currently in the queue.
return count
Destroy Queue
 This function deletes all of the elements in the
queue.
loop (front not null)
dltPtr = front
front = front->next
delete dltPtr
end loop
rear = null
count = 0
Applications
 Computers use queues in a variety of applications:
 To service print requests (the first print job in the queue
gets serviced first … ever have to wait for your print job at
the computer lab?)
 Most computers only have 1 processor so processes must
wait in a queue to get serviced by the processor.
 Packets traveling over the internet arrive at routers and
other internet hardware and are processed in the order in
which they arrive.
A class for Dynamic Queue implementation
class DynIntQueue
{
private:
struct QueueNode
{
int value;
QueueNode *next;
};
QueueNode *front;
QueueNode *rear;
int numItems;
public:
DynIntQueue(void);
~DynIntQueue(void);
void enqueue(int);
int dequeue(void);
bool isEmpty(void);
void makeNull(void);
};
Implemenaton
//************************
// Constructor *
//************************
DynIntQueue::DynIntQueue(void)
{
front = NULL;
rear = NULL;
numItems = 0;
}
//************************
// Destructor *
//************************
DynIntQueue::~DynIntQueue(void)
{
makeNull();
}
//********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue. *
//********************************************
void DynIntQueue::enqueue(int num)
{
QueueNode *newNode;
newNode = new QueueNode;
newNode->value = num;
newNode->next = NULL;
if (isEmpty())
{
front = newNode;
rear = newNode;
}
else
{
rear->next = newNode;
rear = newNode;
}
numItems++;
}
//**********************************************
// Function dequeue removes the value at the *
// front of the queue, and copies it into num. *
//**********************************************
int DynIntQueue::dequeue(void)
{
QueueNode *temp;
int num;
if (isEmpty())
cout << "The queue is empty.n";
else
{
num = front->value;
temp = front->next;
delete front;
front = temp;
numItems--;
}
return num;
}
//*********************************************
// Function isEmpty returns true if the queue *
// is empty, and false otherwise. *
//*********************************************
bool DynIntQueue::isEmpty(void)
{
if (numItems)
return false;
else
return true;
}
//********************************************
// Function makeNull dequeues all the elements *
// in the queue. *
//********************************************
void DynIntQueue::makeNull(void)
{
while(!isEmpty())
dequeue();
}
Program
// This program demonstrates the DynIntQeue class
void main(void)
{
DynIntQueue iQueue;
cout << "Enqueuing 5 items...n";
// Enqueue 5 items.
for (int x = 0; x < 5; x++)
iQueue.enqueue(x);
// Deqeue and retrieve all items in the queue
cout << "The values in the queue were:n";
while (!iQueue.isEmpty())
{
int value;
value =iQueue.dequeue();
cout << value << endl;
}
}
Program Ouput
Enqueuing 5 items...
The values in the queue were:
0
1
2
3
4
Array Implementation
 We can also implement the queue data structure using
an array.
 There are a couple of differences between the linked
list approach and the array approach.
 First, the front and rear of the queue are represented as
indices into the array instead of as pointers.
 Also, we’ll need to store the max number of elements
we can store in the queue (i.e., the size of the array).
 Finally, we can eliminate link fields (the array is a
contiguous structure).
Array Implementation
Array Implementation
First Element
Last Element
maxlength
Front
Second
Element
.
.
Rear
When queue is empty both front
and rear are set to -1
While enqueueing increment
rear by 1, and while dequeueing
increment front by 1
When there is only one value in
the Queue, both rear and front
have same index
Array Implementation
5 4 6 7 8 7 6
0 1 2 3 4 5 6 7 8
Front=0
Rear=6
8 7 6
0 1 2 3 4 5 6 7 8
Front=4
Rear=6
7 6 12 67
0 1 2 3 4 5 6 7 8
Front=5
Rear=8
How can we insert more elements? Rear index can
not move beyond the last element….
Solution: Using circular queue
 Allow rear to wrap around the array.
if(rear == queueSize-1)
rear = 0;
else
rear++;
 Or use module arithmetic
rear = (rear + 1) % queueSize;
7 6 12 67
0 1 2 3 4 5 6 7 8
Front=5
Rear=8
Enqueue 39 Rear=(Rear+1) mod Queue Size = (8+1) mod 9 = 0
39 7 6 12 67
0 1 2 3 4 5 6 7 8
Front=5
Rear=0
Implementation
class IntQueue
{
private:
int *queueArray;
int queueSize;
int front;
int rear;
int numItems;
public:
IntQueue(int);
~IntQueue(void);
void enqueue(int);
int dequeue(void);
bool isEmpty(void);
bool isFull(void);
void clear(void);
};
Note, the member function clear, which clears the queue by resetting the
front and rear indices, and setting the numItems to 0.
IntQueue::IntQueue(int s) //constructor
{
queueArray = new int[s];
queueSize = s;
front = -1;
rear = -1;
numItems = 0;
}
IntQueue::~IntQueue(void) //destructor
{
delete [] queueArray;
}
//********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue. *
//********************************************
void IntQueue::enqueue(int num)
{
if (isFull())
cout << "The queue is full.n";
else
{
// Calculate the new rear position
rear = (rear + 1) % queueSize;
// Insert new item
queueArray[rear] = num;
// Update item count
numItems++;
}
}
//*********************************************
// Function dequeue removes the value at the *
// front of the queue, and copies t into num. *
//*********************************************
int IntQueue::dequeue(void)
{
if (isEmpty())
cout << "The queue is empty.n";
else
{
// Retrieve the front item
int num = queueArray[front];
// Move front
front = (front + 1) % queueSize;
// Update item count
numItems--;
}
return num;
}
//*********************************************
// Function isEmpty returns true if the queue *
// is empty, and false otherwise. *
//*********************************************
bool IntQueue::isEmpty(void)
{
if (numItems)
return false;
else
return true;
}
//********************************************
// Function isFull returns true if the queue *
// is full, and false otherwise. *
//********************************************
bool IntQueue::isFull(void)
{
if (numItems < queueSize)
return false;
else
return true;
}
//*******************************************
// Function clear resets the front and rear *
// indices, and sets numItems to 0. *
//*******************************************
void IntQueue::clear(void)
{
front = - 1;
rear = - 1;
numItems = 0;
}
//Program demonstrating the IntQueue class
void main(void)
{
IntQueue iQueue(5);
cout << "Enqueuing 5 items...n";
// Enqueue 5 items.
for (int x = 0; x < 5; x++)
iQueue.enqueue(x);
// Attempt to enqueue a 6th item.
cout << "Now attempting to enqueue again...n";
iQueue.enqueue(5);
// Deqeue and retrieve all items in the queue
cout << "The values in the queue were:n";
while (!iQueue.isEmpty())
{
int value;
iQueue.dequeue(value);
cout << value << endl;
}
}
Program Output
Enqueuing 5 items...
Now attempting to enqueue again...
The queue is full.
The values in the queue were:
0
1
2
3
4
Another implementation of Queues
using Arrays
class CQueue
{
int Data*,QueueSize,Front,Rear;
public:
CQueue(int size);
~CQueue(int size);
bool IsFull();
bool IsEmpty();
void Enqueue(int num);
int Dequeue();
void MakeNull;
};
CQueue::CQueue(int size)
{
Front=Rear=-1;
Data=new int[size];
}
void CQueue ::Enqueue(int num);
{
if (IsFull()) { cout<<“Overflow” return; }
if (IsEmpty() Rear=Front=0;
else Rear=(Rear+1) % QueueSize;
Data[Rear]=num;
}
int CQueue ::Dequeue(int num);
{
if (IsEmpty()) { cout<<“Underflow”; return; }
int ReturnValue=Data[Front];
if (Front==Rear) //only one element in the queue
Front=Rear=-1;
else
Front=(Front+1) % QueueSize;
return ReturnValue;
}
bool CQueue::IsEmpty()
{
if (Front==-1) return true;
else return false;
}
bool CQueue::IsFull()
{
If (((Rear+1)%QueueSize)==Front)
return true;
else return false;
}

Lec-07 Queues.ppt queues introduction to queue

  • 1.
  • 2.
    Introduction to Queues The queue data structure is very similar to the stack.  In a stack, all insertions and deletions occur at one end, the top, of the list.  In the queue, as in the stack, all deletions occur at the head (front) of the list.  However, all insertions to the queue occur at the tail (back or rear) of the list.
  • 3.
    Introduction to Queues Basically, data enters the queue at one end and exits at the other end.  This characteristic gives a queue its first-in, first-out (FIFO) behavior.
  • 4.
    ADT Queue Collection ofData Elements: 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 rear (end) of the queue Basic Operations: 1. MAKENULL(Q): Makes Queue Q be an empty list. 2. FRONT(Q): Returns the first element on Queue Q. 3. ENQUEUE(x,Q): Inserts element x at the rear (end) of Queue Q. 4. DEQUEUE(Q): Deletes the first element of Q. 5. EMPTY(Q): Returns true if and only if Q is an empty queue.
  • 5.
    Implementation  Static Queue isimplemented by an array, and size of queue remains fix  Dynamic A queue can be implemented as a linked list, and expand or shrink with each enqueue or dequeue operation.
  • 6.
    Enqueue  The queueinsert is known as enqueue.  After the data has been inserted, this new element becomes the rear of the queue.
  • 7.
    Dequeue  The queuedelete operation is known as dequeue.  The data at the front of the queue is returned to the user and deleted from the queue.
  • 9.
    Queue Front  Dataat the front of the queue can be examined with queue front.  This function returns the data at the front of the queue but does not remove it from the queue.
  • 10.
    Queue Rear  Similarto queue front is queue rear.  This function examines the data stored in the rear element of the queue, but does not remove it.
  • 11.
  • 12.
  • 13.
    Linked List Implementation Several data structures could be used to implement a queue (including an array).  However, we will discuss a linked list implementation first.  As with any linked list, we have 2 structures: List Node
  • 14.
    Linked List Implementation The List structure contains the metadata (e.g., number of elements in the queue) and pointers to the front and rear elements of the queue.  The Node structure contains the data and a pointer to the next element in the queue.
  • 15.
  • 16.
    Queue Algorithms  Wenow develop the pseudocode to implement some basic operations that can be performed on a queue.  Then, we will discuss an actual C++ implementation.
  • 17.
    Create Queue  Thisfunction initializes the metadata for the queue structure. ? ? count front queue 0 count = 0 Pseudocode front = NULL rear = NULL rear ? 0 0
  • 18.
    Enqueue  This functioninserts an element into the queue.  We need to: Allocate memory for the new node. Update the link field of the rear node to point to the new rear (the inserted element). Update the rear pointer to point to the new rear element of the queue. Increment the count of nodes in the queue.
  • 19.
    Enqueue Pseudocode rear->link = pNew queue rear= pNew Here, we want to insert our new node into the queue. count front 0 75 pNew 1 39 2 0 rear
  • 20.
    Enqueue Pseudocode if( countis zero ) front = pNew else rear->next = pNew end if rear = pNew count++
  • 21.
    Dequeue  This functionremoves an element from the queue.  We need to: Return the data at the front of the queue. Recycle the memory from the front node. Update the front pointer to point to the new front of the queue. Decrement the count of nodes in the queue.
  • 22.
    Dequeue Pseudocode dltPtr = front 3 countfront queue 134 39 Here, we want to remove the first node in the queue (39). 75 0 dltPtr delete dltPtr (available) 2 dataOut = front->data front = front->link 0 dataOut rear
  • 23.
    Dequeue Pseudocode if( queuenot empty ) dltPtr = front dataOut = front->data front = front->link delete dltPtr count-- if( count == 0) rear = NULL end if end if
  • 24.
    Queue Front  Thisfunction returns the data from the front of the queue, but does not remove the node from the queue. if (queue empty) success = false else dataOut = front->data success = true end if return success
  • 25.
    Queue Rear  Thisfunction returns the data from the rear of the queue, but does not remove the node from the queue. if (queue empty) success = false else dataOut = rear->data success = true end if return success
  • 26.
    IsEmpty Queue  Thisfunction checks to see if the queue is empty. if (queue empty) return true else return false end if
  • 27.
    Queue Count  Thisfunction returns the number of elements currently in the queue. return count
  • 28.
    Destroy Queue  Thisfunction deletes all of the elements in the queue. loop (front not null) dltPtr = front front = front->next delete dltPtr end loop rear = null count = 0
  • 29.
    Applications  Computers usequeues in a variety of applications:  To service print requests (the first print job in the queue gets serviced first … ever have to wait for your print job at the computer lab?)  Most computers only have 1 processor so processes must wait in a queue to get serviced by the processor.  Packets traveling over the internet arrive at routers and other internet hardware and are processed in the order in which they arrive.
  • 30.
    A class forDynamic Queue implementation class DynIntQueue { private: struct QueueNode { int value; QueueNode *next; }; QueueNode *front; QueueNode *rear; int numItems; public: DynIntQueue(void); ~DynIntQueue(void); void enqueue(int); int dequeue(void); bool isEmpty(void); void makeNull(void); };
  • 31.
    Implemenaton //************************ // Constructor * //************************ DynIntQueue::DynIntQueue(void) { front= NULL; rear = NULL; numItems = 0; } //************************ // Destructor * //************************ DynIntQueue::~DynIntQueue(void) { makeNull(); }
  • 32.
    //******************************************** // Function enqueueinserts the value in num * // at the rear of the queue. * //******************************************** void DynIntQueue::enqueue(int num) { QueueNode *newNode; newNode = new QueueNode; newNode->value = num; newNode->next = NULL; if (isEmpty()) { front = newNode; rear = newNode; } else { rear->next = newNode; rear = newNode; } numItems++; }
  • 33.
    //********************************************** // Function dequeueremoves the value at the * // front of the queue, and copies it into num. * //********************************************** int DynIntQueue::dequeue(void) { QueueNode *temp; int num; if (isEmpty()) cout << "The queue is empty.n"; else { num = front->value; temp = front->next; delete front; front = temp; numItems--; } return num; }
  • 34.
    //********************************************* // Function isEmptyreturns true if the queue * // is empty, and false otherwise. * //********************************************* bool DynIntQueue::isEmpty(void) { if (numItems) return false; else return true; }
  • 35.
    //******************************************** // Function makeNulldequeues all the elements * // in the queue. * //******************************************** void DynIntQueue::makeNull(void) { while(!isEmpty()) dequeue(); }
  • 36.
    Program // This programdemonstrates the DynIntQeue class void main(void) { DynIntQueue iQueue; cout << "Enqueuing 5 items...n"; // Enqueue 5 items. for (int x = 0; x < 5; x++) iQueue.enqueue(x); // Deqeue and retrieve all items in the queue cout << "The values in the queue were:n"; while (!iQueue.isEmpty()) { int value; value =iQueue.dequeue(); cout << value << endl; } }
  • 37.
    Program Ouput Enqueuing 5items... The values in the queue were: 0 1 2 3 4
  • 38.
    Array Implementation  Wecan also implement the queue data structure using an array.  There are a couple of differences between the linked list approach and the array approach.  First, the front and rear of the queue are represented as indices into the array instead of as pointers.  Also, we’ll need to store the max number of elements we can store in the queue (i.e., the size of the array).  Finally, we can eliminate link fields (the array is a contiguous structure).
  • 39.
  • 40.
    Array Implementation First Element LastElement maxlength Front Second Element . . Rear When queue is empty both front and rear are set to -1 While enqueueing increment rear by 1, and while dequeueing increment front by 1 When there is only one value in the Queue, both rear and front have same index
  • 41.
    Array Implementation 5 46 7 8 7 6 0 1 2 3 4 5 6 7 8 Front=0 Rear=6 8 7 6 0 1 2 3 4 5 6 7 8 Front=4 Rear=6 7 6 12 67 0 1 2 3 4 5 6 7 8 Front=5 Rear=8 How can we insert more elements? Rear index can not move beyond the last element….
  • 42.
    Solution: Using circularqueue  Allow rear to wrap around the array. if(rear == queueSize-1) rear = 0; else rear++;  Or use module arithmetic rear = (rear + 1) % queueSize;
  • 43.
    7 6 1267 0 1 2 3 4 5 6 7 8 Front=5 Rear=8 Enqueue 39 Rear=(Rear+1) mod Queue Size = (8+1) mod 9 = 0 39 7 6 12 67 0 1 2 3 4 5 6 7 8 Front=5 Rear=0
  • 44.
    Implementation class IntQueue { private: int *queueArray; intqueueSize; int front; int rear; int numItems; public: IntQueue(int); ~IntQueue(void); void enqueue(int); int dequeue(void); bool isEmpty(void); bool isFull(void); void clear(void); }; Note, the member function clear, which clears the queue by resetting the front and rear indices, and setting the numItems to 0.
  • 45.
    IntQueue::IntQueue(int s) //constructor { queueArray= new int[s]; queueSize = s; front = -1; rear = -1; numItems = 0; } IntQueue::~IntQueue(void) //destructor { delete [] queueArray; }
  • 46.
    //******************************************** // Function enqueueinserts the value in num * // at the rear of the queue. * //******************************************** void IntQueue::enqueue(int num) { if (isFull()) cout << "The queue is full.n"; else { // Calculate the new rear position rear = (rear + 1) % queueSize; // Insert new item queueArray[rear] = num; // Update item count numItems++; } }
  • 47.
    //********************************************* // Function dequeueremoves the value at the * // front of the queue, and copies t into num. * //********************************************* int IntQueue::dequeue(void) { if (isEmpty()) cout << "The queue is empty.n"; else { // Retrieve the front item int num = queueArray[front]; // Move front front = (front + 1) % queueSize; // Update item count numItems--; } return num; }
  • 48.
    //********************************************* // Function isEmptyreturns true if the queue * // is empty, and false otherwise. * //********************************************* bool IntQueue::isEmpty(void) { if (numItems) return false; else return true; }
  • 49.
    //******************************************** // Function isFullreturns true if the queue * // is full, and false otherwise. * //******************************************** bool IntQueue::isFull(void) { if (numItems < queueSize) return false; else return true; }
  • 50.
    //******************************************* // Function clearresets the front and rear * // indices, and sets numItems to 0. * //******************************************* void IntQueue::clear(void) { front = - 1; rear = - 1; numItems = 0; }
  • 51.
    //Program demonstrating theIntQueue class void main(void) { IntQueue iQueue(5); cout << "Enqueuing 5 items...n"; // Enqueue 5 items. for (int x = 0; x < 5; x++) iQueue.enqueue(x); // Attempt to enqueue a 6th item. cout << "Now attempting to enqueue again...n"; iQueue.enqueue(5); // Deqeue and retrieve all items in the queue cout << "The values in the queue were:n"; while (!iQueue.isEmpty()) { int value; iQueue.dequeue(value); cout << value << endl; } }
  • 52.
    Program Output Enqueuing 5items... Now attempting to enqueue again... The queue is full. The values in the queue were: 0 1 2 3 4
  • 53.
    Another implementation ofQueues using Arrays class CQueue { int Data*,QueueSize,Front,Rear; public: CQueue(int size); ~CQueue(int size); bool IsFull(); bool IsEmpty(); void Enqueue(int num); int Dequeue(); void MakeNull; };
  • 54.
    CQueue::CQueue(int size) { Front=Rear=-1; Data=new int[size]; } voidCQueue ::Enqueue(int num); { if (IsFull()) { cout<<“Overflow” return; } if (IsEmpty() Rear=Front=0; else Rear=(Rear+1) % QueueSize; Data[Rear]=num; }
  • 55.
    int CQueue ::Dequeue(intnum); { if (IsEmpty()) { cout<<“Underflow”; return; } int ReturnValue=Data[Front]; if (Front==Rear) //only one element in the queue Front=Rear=-1; else Front=(Front+1) % QueueSize; return ReturnValue; }
  • 56.
    bool CQueue::IsEmpty() { if (Front==-1)return true; else return false; } bool CQueue::IsFull() { If (((Rear+1)%QueueSize)==Front) return true; else return false; }